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 *.txt
include bonobo/bonobo.svg
recursive-include bonobo *.py-tpl recursive-include bonobo *.py-tpl

View File

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

View File

@ -17,11 +17,19 @@ environment:
PYTHON_ARCH: "64" PYTHON_ARCH: "64"
- PYTHON: "C:\\Python36" - PYTHON: "C:\\Python36"
PYTHON_VERSION: "3.6.1" PYTHON_VERSION: "3.6.7"
PYTHON_ARCH: "32" PYTHON_ARCH: "32"
- PYTHON: "C:\\Python36-x64" - 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" PYTHON_ARCH: "64"
build: false build: false

View File

@ -16,11 +16,11 @@ import timeit
def j1(d): def j1(d):
return {'prepend': 'foo', **d, 'append': 'bar'} return {"prepend": "foo", **d, "append": "bar"}
def k1(**d): def k1(**d):
return {'prepend': 'foo', **d, 'append': 'bar'} return {"prepend": "foo", **d, "append": "bar"}
def j2(d): def j2(d):
@ -39,17 +39,17 @@ def k3(**d):
return None return None
if __name__ == '__main__': if __name__ == "__main__":
import timeit import timeit
with open('person.json') as f: with open("person.json") as f:
json_data = json.load(f) json_data = json.load(f)
for i in 1, 2, 3: for i in 1, 2, 3:
print( 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( print(
'k{}'.format(i), "k{}".format(i),
timeit.timeit("k{}(**{!r})".format(i, json_data), setup="from __main__ import 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 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: class Module:
def __init__(self, name, title=None, *, automodule_options=None): def __init__(self, name, title=None, *, automodule_options=None):
self.name = name 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() self.automodule_options = automodule_options or list()
def __repr__(self): def __repr__(self):
return '<{} ({})>'.format(self.title, self.name) return "<{} ({})>".format(self.title, self.name)
def asdict(self): 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): 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 = [ modules = [
Module('bonobo', title='Bonobo'), Module("bonobo", title="Bonobo"),
Module('bonobo.config'), Module("bonobo.config"),
Module('bonobo.constants', automodule_options=['no-members']), Module("bonobo.constants", automodule_options=["no-members"]),
Module('bonobo.execution'), Module("bonobo.execution"),
Module('bonobo.execution.contexts'), Module("bonobo.execution.contexts"),
Module('bonobo.execution.events'), Module("bonobo.execution.events"),
Module('bonobo.execution.strategies'), Module("bonobo.execution.strategies"),
Module('bonobo.util'), Module("bonobo.util"),
] ]
def underlined_filter(txt, chr): def underlined_filter(txt, chr):
return txt + '\n' + chr * len(txt) return txt + "\n" + chr * len(txt)
env = Environment( env = Environment(
loader=DictLoader( loader=DictLoader(
{ {
'module': ''' "module": """
{{ (':mod:`'~title~' <'~name~'>`') | underlined('=') }} {{ (':mod:`'~title~' <'~name~'>`') | underlined('=') }}
.. currentmodule:: {{ name }} .. currentmodule:: {{ name }}
@ -52,15 +52,15 @@ env = Environment(
.. automodule:: {{ name }} .. automodule:: {{ name }}
{% for opt in automodule_options %} :{{ opt }}:{{ "\n" }}{% endfor %} {% for opt in automodule_options %} :{{ opt }}:{{ "\n" }}{% endfor %}
'''[ """[
1:-1 1:-1
] ]
+ '\n' + "\n"
} }
) )
) )
env.filters['underlined'] = underlined_filter env.filters["underlined"] = underlined_filter
for module in modules: for module in modules:
with open(module.get_path(), 'w+') as f: with open(module.get_path(), "w+") as f:
f.write(env.get_template('module').render(module.asdict())) 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. to another is maximal.
""" """
from bonobo.execution.strategies import create_strategy from bonobo.execution.strategies import create_strategy
from bonobo.nodes import * from bonobo.nodes import *
from bonobo.nodes import __all__ as _all_nodes from bonobo.nodes import __all__ as _all_nodes
@ -187,7 +186,7 @@ def get_examples_path(*pathsegments):
import os import os
import pathlib import pathlib
return str(pathlib.Path(os.path.dirname(__file__), 'examples', *pathsegments)) return str(pathlib.Path(os.path.dirname(__file__), "examples", *pathsegments))
@api.register @api.register
@ -196,3 +195,4 @@ def open_examples_fs(*pathsegments):
api.register_group(get_argument_parser, parse_args) 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 import sys
from contextlib import contextmanager from contextlib import contextmanager
from mondrian import humanizer
import bonobo.util.environ import bonobo.util.environ
from bonobo.util import get_name from bonobo.util import get_name
from bonobo.util.environ import get_argument_parser, parse_args from bonobo.util.environ import get_argument_parser, parse_args
from mondrian import humanizer
class BaseCommand: class BaseCommand:

View File

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

View File

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

View File

@ -1,6 +1,7 @@
from bonobo.commands import BaseCommand
from mondrian import humanizer from mondrian import humanizer
from bonobo.commands import BaseCommand
def get_versions(*, all=False, quiet=None): def get_versions(*, all=False, quiet=None):
import bonobo 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.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.options import Method, Option
from bonobo.config.processors import ContextProcessor, use_context, use_context_processor, use_raw_input, use_no_input 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 from bonobo.config.services import Container, Exclusive, Service, use, create_container
@ -23,6 +23,7 @@ __all__ = [
"Option", "Option",
"Service", "Service",
"create_container", "create_container",
"partial",
"requires", "requires",
"transformation_factory", "transformation_factory",
"use", "use",

View File

@ -1,6 +1,9 @@
import functools import functools
import itertools import itertools
from bonobo.config.services import use
from bonobo.util import get_name
def transformation_factory(f): def transformation_factory(f):
@functools.wraps(f) @functools.wraps(f)
@ -14,3 +17,11 @@ def transformation_factory(f):
_transformation_factory._partial = True _transformation_factory._partial = True
return _transformation_factory 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 contextlib import contextmanager
from functools import partial from functools import partial
from inspect import signature from inspect import signature

View File

@ -68,7 +68,7 @@ class Container(dict):
if len(args) == 1: if len(args) == 1:
if len(kwargs): if len(kwargs):
raise ValueError( 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__ cls.__name__
) )
) )

View File

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

View File

@ -134,7 +134,7 @@ def BagType(typename, fields, *, verbose=False, module=None):
if type(name) is not str: 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 isinstance(name, str): 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 i:
if not name.isidentifier(): 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))

View File

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

View File

@ -24,7 +24,7 @@ def sweeten_errors():
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 = 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) return (arg, length)

View File

@ -1,2 +1,2 @@
CLEAR_EOL = "\033[0K" 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): def update_context(app, pagename, templatename, context, doctree):
context['alabaster_version'] = version.__version__ context["alabaster_version"] = version.__version__
def setup(app): def setup(app):
# add_html_theme is new in Sphinx 1.6+ # 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__)) theme_path = os.path.abspath(os.path.dirname(__file__))
app.add_html_theme('alabaster', theme_path) app.add_html_theme("alabaster", theme_path)
app.connect('html-page-context', update_context) app.connect("html-page-context", update_context)
return {'version': version.__version__, 'parallel_read_safe': True} return {"version": version.__version__, "parallel_read_safe": True}

View File

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

View File

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

View File

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

View File

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

105
setup.py
View File

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

View File

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

View File

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