Fix #249: Quoting format is integer, not string.

This commit is contained in:
Romain Dorgueil
2018-02-03 17:11:23 +01:00
parent aa6e426768
commit 02eeaff883
19 changed files with 68 additions and 47 deletions

View File

@ -1,4 +1,4 @@
# Generated by Medikit 0.4.3 on 2018-01-16. # Generated by Medikit 0.4.7 on 2018-02-03.
# All changes will be overriden. # All changes will be overriden.
PACKAGE ?= bonobo PACKAGE ?= bonobo

View File

@ -70,11 +70,17 @@ python.add_requirements(
], ],
) )
@listen(make.on_generate) @listen(make.on_generate)
def on_make_generate(event): def on_make_generate(event):
event.makefile['SPHINX_AUTOBUILD'] = '$(PYTHON_DIRNAME)/sphinx-autobuild' event.makefile['SPHINX_AUTOBUILD'] = '$(PYTHON_DIRNAME)/sphinx-autobuild'
event.makefile.add_target('watch-$(SPHINX_SOURCEDIR)', ''' event.makefile.add_target(
'watch-$(SPHINX_SOURCEDIR)',
'''
$(SPHINX_AUTOBUILD) $(SPHINX_SOURCEDIR) $(shell mktemp -d) $(SPHINX_AUTOBUILD) $(SPHINX_SOURCEDIR) $(shell mktemp -d)
''', phony=True) ''',
phony=True
)
# vim: ft=python: # vim: ft=python:

View File

@ -40,13 +40,14 @@ modules = [
] ]
def underlined_filter(txt, chr): def underlined_filter(txt, chr):
return txt + '\n' + chr * len(txt) return txt + '\n' + chr * len(txt)
env = Environment(loader=DictLoader({ env = Environment(
'module': ''' loader=DictLoader({
'module':
'''
{{ (':mod:`'~title~' <'~name~'>`') | underlined('=') }} {{ (':mod:`'~title~' <'~name~'>`') | underlined('=') }}
.. currentmodule:: {{ name }} .. currentmodule:: {{ name }}
@ -55,7 +56,9 @@ env = Environment(loader=DictLoader({
.. automodule:: {{ name }} .. automodule:: {{ name }}
{% for opt in automodule_options %} :{{ opt }}:{{ "\n" }}{% endfor %} {% for opt in automodule_options %} :{{ opt }}:{{ "\n" }}{% endfor %}
'''[1:-1] + '\n'})) ''' [1:-1] + '\n'
})
)
env.filters['underlined'] = underlined_filter env.filters['underlined'] = underlined_filter
for module in modules: for module in modules:

View File

@ -47,15 +47,7 @@ class ConfigurableMeta(type):
prefix = ':param {}: '.format(_param) prefix = ':param {}: '.format(_param)
for lineno, line in enumerate((_value.__doc__ or '').split('\n')): for lineno, line in enumerate((_value.__doc__ or '').split('\n')):
_options_doc.append((' ' * len(prefix) if lineno else prefix) + line) _options_doc.append((' ' * len(prefix) if lineno else prefix) + line)
cls.__doc__ = '\n\n'.join( cls.__doc__ = '\n\n'.join(map(str.strip, filter(None, (cls.__doc__, '\n'.join(_options_doc)))))
map(
str.strip,
filter(None, (
cls.__doc__,
'\n'.join(_options_doc)
))
)
)
@property @property
def __options__(cls): def __options__(cls):

View File

@ -56,7 +56,7 @@ class ETLCommand(BaseCommand):
graph_coll = self.get_graph(*args, **options) graph_coll = self.get_graph(*args, **options)
if not isinstance(graph_coll, GeneratorType): if not isinstance(graph_coll, GeneratorType):
graph_coll = (graph_coll,) graph_coll = (graph_coll, )
for i, graph in enumerate(graph_coll): for i, graph in enumerate(graph_coll):
assert isinstance(graph, bonobo.Graph), 'Invalid graph provided.' assert isinstance(graph, bonobo.Graph), 'Invalid graph provided.'

View File

@ -12,9 +12,11 @@ class FileHandler(Configurable):
encoding (str): which encoding to use when opening the file. encoding (str): which encoding to use when opening the file.
""" """
path = Option(str, required=True, positional=True, __doc__=''' path = Option(
str, required=True, positional=True, __doc__='''
Path to use within the provided filesystem. Path to use within the provided filesystem.
''') # type: str '''
) # type: str
eol = Option(str, default='\n', __doc__=''' eol = Option(str, default='\n', __doc__='''
Character to use as line separator. Character to use as line separator.
''') # type: str ''') # type: str

View File

@ -33,7 +33,7 @@ class CsvHandler(FileHandler):
doublequote = Option(str, default=csv.excel.doublequote, required=False) doublequote = Option(str, default=csv.excel.doublequote, required=False)
skipinitialspace = Option(str, default=csv.excel.skipinitialspace, required=False) skipinitialspace = Option(str, default=csv.excel.skipinitialspace, required=False)
lineterminator = Option(str, default=csv.excel.lineterminator, required=False) lineterminator = Option(str, default=csv.excel.lineterminator, required=False)
quoting = Option(str, default=csv.excel.quoting, required=False) quoting = Option(int, default=csv.excel.quoting, required=False)
# Fields (renamed from headers) # Fields (renamed from headers)
headers = RenamedOption('fields') headers = RenamedOption('fields')
@ -57,9 +57,13 @@ class CsvReader(FileReader, CsvHandler):
Reads a CSV and yield the values as dicts. Reads a CSV and yield the values as dicts.
""" """
skip = Option(int, default=0, __doc__=''' skip = Option(
int,
default=0,
__doc__='''
If set and greater than zero, the reader will skip this amount of lines. If set and greater than zero, the reader will skip this amount of lines.
''') '''
)
@Method( @Method(
positional=False, positional=False,

View File

@ -151,7 +151,10 @@ class Graph:
return '<strong>{}</strong>: {}'.format(type(exc).__name__, str(exc)) return '<strong>{}</strong>: {}'.format(type(exc).__name__, str(exc))
def _resolve_index(self, mixed): def _resolve_index(self, mixed):
""" Find the index based on various strategies for a node, probably an input or output of chain. Supported inputs are indexes, node values or names. """
Find the index based on various strategies for a node, probably an input or output of chain. Supported
inputs are indexes, node values or names.
""" """
if mixed is None: if mixed is None:
return None return None

View File

@ -14,8 +14,8 @@ class ApiHelper:
from inspect import signature from inspect import signature
parameters = list(signature(x).parameters) parameters = list(signature(x).parameters)
required_parameters = {'plugins', 'services', 'strategy'} required_parameters = {'plugins', 'services', 'strategy'}
assert len(parameters) > 0 and parameters[ assert len(parameters
0] == 'graph', 'First parameter of a graph api function must be "graph".' ) > 0 and parameters[0] == 'graph', 'First parameter of a graph api function must be "graph".'
assert required_parameters.intersection( assert required_parameters.intersection(
parameters parameters
) == required_parameters, 'Graph api functions must define the following parameters: ' + ', '.join( ) == required_parameters, 'Graph api functions must define the following parameters: ' + ', '.join(

View File

@ -26,7 +26,7 @@ def ensure_tuple(tuple_or_mixed, *, cls=tuple):
if isinstance(tuple_or_mixed, tuple): 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,)) return tuple.__new__(cls, (tuple_or_mixed, ))
def cast(type_): def cast(type_):

View File

@ -61,10 +61,13 @@ language = None
# 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'

View File

@ -1,10 +1,10 @@
-e .[dev] -e .[dev]
alabaster==0.7.10 alabaster==0.7.10
arrow==0.12.0 arrow==0.12.1
attrs==17.4.0 attrs==17.4.0
babel==2.5.3 babel==2.5.3
binaryornot==0.4.4 binaryornot==0.4.4
certifi==2017.11.5 certifi==2018.1.18
chardet==3.0.4 chardet==3.0.4
click==6.7 click==6.7
cookiecutter==1.5.1 cookiecutter==1.5.1
@ -23,7 +23,7 @@ pygments==2.2.0
pytest-cov==2.5.1 pytest-cov==2.5.1
pytest-sugar==0.8.0 pytest-sugar==0.8.0
pytest-timeout==1.2.1 pytest-timeout==1.2.1
pytest==3.3.2 pytest==3.4.0
python-dateutil==2.6.1 python-dateutil==2.6.1
pytz==2017.3 pytz==2017.3
requests==2.18.4 requests==2.18.4

View File

@ -1,12 +1,12 @@
-e .[docker] -e .[docker]
appdirs==1.4.3 appdirs==1.4.3
bonobo-docker==0.6.0 bonobo-docker==0.6.0
certifi==2017.11.5 certifi==2018.1.18
chardet==3.0.4 chardet==3.0.4
colorama==0.3.9 colorama==0.3.9
docker-pycreds==0.2.1 docker-pycreds==0.2.1
docker==2.7.0 docker==2.7.0
fs==2.0.17 fs==2.0.18
graphviz==0.8.2 graphviz==0.8.2
idna==2.6 idna==2.6
jinja2==2.10 jinja2==2.10

View File

@ -4,14 +4,14 @@ bleach==2.1.2
decorator==4.2.1 decorator==4.2.1
entrypoints==0.2.3 entrypoints==0.2.3
html5lib==1.0.1 html5lib==1.0.1
ipykernel==4.7.0 ipykernel==4.8.0
ipython-genutils==0.2.0 ipython-genutils==0.2.0
ipython==6.2.1 ipython==6.2.1
ipywidgets==6.0.1 ipywidgets==6.0.1
jedi==0.11.1 jedi==0.11.1
jinja2==2.10 jinja2==2.10
jsonschema==2.6.0 jsonschema==2.6.0
jupyter-client==5.2.1 jupyter-client==5.2.2
jupyter-console==5.2.0 jupyter-console==5.2.0
jupyter-core==4.4.0 jupyter-core==4.4.0
jupyter==1.0.0 jupyter==1.0.0
@ -19,7 +19,7 @@ markupsafe==1.0
mistune==0.8.3 mistune==0.8.3
nbconvert==5.3.1 nbconvert==5.3.1
nbformat==4.4.0 nbformat==4.4.0
notebook==5.2.2 notebook==5.4.0
pandocfilters==1.4.2 pandocfilters==1.4.2
parso==0.1.1 parso==0.1.1
pexpect==4.3.1 pexpect==4.3.1
@ -28,8 +28,9 @@ prompt-toolkit==1.0.15
ptyprocess==0.5.2 ptyprocess==0.5.2
pygments==2.2.0 pygments==2.2.0
python-dateutil==2.6.1 python-dateutil==2.6.1
pyzmq==16.0.3 pyzmq==16.0.4
qtconsole==4.3.1 qtconsole==4.3.1
send2trash==1.4.2
simplegeneric==0.8.1 simplegeneric==0.8.1
six==1.11.0 six==1.11.0
terminado==0.8.1 terminado==0.8.1

View File

@ -1,10 +1,10 @@
-e .[sqlalchemy] -e .[sqlalchemy]
appdirs==1.4.3 appdirs==1.4.3
bonobo-sqlalchemy==0.6.0 bonobo-sqlalchemy==0.6.0
certifi==2017.11.5 certifi==2018.1.18
chardet==3.0.4 chardet==3.0.4
colorama==0.3.9 colorama==0.3.9
fs==2.0.17 fs==2.0.18
graphviz==0.8.2 graphviz==0.8.2
idna==2.6 idna==2.6
jinja2==2.10 jinja2==2.10
@ -18,7 +18,7 @@ python-slugify==1.2.4
pytz==2017.3 pytz==2017.3
requests==2.18.4 requests==2.18.4
six==1.11.0 six==1.11.0
sqlalchemy==1.2.1 sqlalchemy==1.2.2
stevedore==1.28.0 stevedore==1.28.0
unidecode==1.0.22 unidecode==1.0.22
urllib3==1.22 urllib3==1.22

View File

@ -1,9 +1,9 @@
-e . -e .
appdirs==1.4.3 appdirs==1.4.3
certifi==2017.11.5 certifi==2018.1.18
chardet==3.0.4 chardet==3.0.4
colorama==0.3.9 colorama==0.3.9
fs==2.0.17 fs==2.0.18
graphviz==0.8.2 graphviz==0.8.2
idna==2.6 idna==2.6
jinja2==2.10 jinja2==2.10

View File

@ -1,5 +1,3 @@
import pprint
import pytest import pytest
from bonobo.config.configurables import Configurable from bonobo.config.configurables import Configurable

View File

@ -1,11 +1,13 @@
from collections import namedtuple from collections import namedtuple
from csv import QUOTE_ALL
from unittest import TestCase from unittest import TestCase
import pytest import pytest
from bonobo import CsvReader, CsvWriter from bonobo import CsvReader, CsvWriter
from bonobo.constants import EMPTY from bonobo.constants import EMPTY
from bonobo.util.testing import FilesystemTester, BufferingNodeExecutionContext, WriterTest, ConfigurableNodeTest, ReaderTest from bonobo.util.testing import FilesystemTester, BufferingNodeExecutionContext, WriterTest, ConfigurableNodeTest, \
ReaderTest
csv_tester = FilesystemTester('csv') 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.input_data = 'a,b,c\na foo,b foo,c foo\na bar,b bar,c bar'
@ -90,6 +92,13 @@ class CsvReaderTest(Csv, ReaderTest, TestCase):
self.check_output(context) 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')
class CsvWriterTest(Csv, WriterTest, TestCase): class CsvWriterTest(Csv, WriterTest, TestCase):
@incontext() @incontext()

View File

@ -14,8 +14,8 @@ def test_sortedlist():
def test_ensure_tuple(): def test_ensure_tuple():
assert ensure_tuple('a') == ('a',) assert ensure_tuple('a') == ('a', )
assert ensure_tuple(('a',)) == ('a',) assert ensure_tuple(('a', )) == ('a', )
assert ensure_tuple(()) is () assert ensure_tuple(()) is ()