Compare commits

...

31 Commits

Author SHA1 Message Date
Iuri de Silvio 6afe716d64 Version bump: 0.11.4 2017-01-23 19:10:36 -02:00
Iuri de Silvio 3d44bdec40 Merge pull request #269 from kammala/master
Fixed classifiers in setup.py
2017-01-10 10:14:11 -02:00
kammala 319505817a Fixed classifiers in setup.py
moved classifiers from tuple to list(this allow to use setup.py upload command in python >= 3.5)
2017-01-10 12:20:08 +03:00
kennethreitz 6cb9a69746 Merge pull request #266 from wenzhihong2003/master
remove file must be close it.
2017-01-05 12:51:01 -05:00
tomwen bb1354b61f remove file must be close it.
in windows if you don't close template file, remove it will raise

WindowsError: [Error 32]
2016-12-30 10:21:43 +08:00
Iuri de Silvio ddc4bd30f2 Merge pull request #234 from BrianPainter/master
if the object is a decimal, return the string representation of it.
2016-12-18 19:10:18 -02:00
Iuri de Silvio 52e547daf9 Merge pull request #259 from dyve/master
Fix #260 date and datetime export to JSON
2016-12-18 19:09:26 -02:00
Iuri de Silvio 7f0b7a0a22 Merge pull request #263 from andriisoldatenko/develop
Remove LOCALE from str regular expression
2016-12-18 19:08:41 -02:00
Andrii Soldatenko ddac443732 Added py36 to tox.ini 2016-12-18 17:04:28 +02:00
Andrii Soldatenko e13f4d0aba Added py35 to tox.ini 2016-12-18 16:54:22 +02:00
Andrii Soldatenko 54f9041f2c Remove LOCALE from str regular expression 2016-12-18 16:44:18 +02:00
Dylan Verheul 91d3299280 Fix date and datetime export to JSON in Python versions with a json package
Python without a json package will use omnijson and fail on date and datetime objects.
Added unit tests.
2016-11-30 12:32:47 +01:00
kennethreitz f59abe84be Merge pull request #239 from ErwinJunge/dataset-title-in-docs
Put Dataset.title in the documentation
2016-05-21 15:13:30 -04:00
Erwin Junge cf23f2344f Put Dataset.title in the documentation 2016-05-20 16:13:22 +02:00
kennethreitz e16bb38c48 Merge pull request #238 from sushrutrathi/code_changes
changes in code refactoring
2016-05-03 21:30:25 -04:00
Sushrut Rathi 71ca275dd1 changes in code refactoring 2016-05-03 13:47:25 +05:30
kennethreitz 75bbfbbaf4 Merge pull request #233 from ScorpionResponse/html_book_test
Add HTML format to the book_export test and fix the format to work properly
2016-04-10 18:12:37 -04:00
Iuri de Silvio b35d505621 Merge pull request #236 from candy0427/master
Update README.rst
2016-03-24 10:18:34 -03:00
CandyLikeSmile cd491c062c Update README.rst 2016-03-24 14:19:59 +08:00
Brian Painter 9fdb72cc5c if the object is a decimal, return the string representation of it. 2016-03-23 08:21:36 -04:00
kennethreitz a5b1f7987e Merge pull request #232 from chimeno/patch-1
[docs] Update variable name in tuto
2016-03-18 14:37:19 -04:00
Paul Moss 8cf6770a76 Add HTML format to the book_export test and fix the format to work properly 2016-03-18 18:17:19 +00:00
Daniel Chimeno 5fa3d2f886 [docs] Update variable name in tuto
The tutorial has been using the 'data' variable, but in this case it's using 'd'.
This change that.
2016-03-18 09:22:59 +01:00
kennethreitz d4c66c7a4e Merge pull request #229 from pmlandwehr/patch-1
python 3 fix: map filter to ifilter
2016-02-28 00:20:37 -05:00
Peter M. Landwehr af17586581 python 3 fix: map filter to ifilter 2016-02-27 21:14:13 -08:00
kennethreitz 23d21f00f3 Update HISTORY.rst 2016-02-25 12:59:18 -05:00
kennethreitz 7ee924b5a6 Merge pull request #228 from tomchristie/print-dataset-with-no-headers
Fixed textual representation for Dataset with no headers
2016-02-25 12:58:35 -05:00
Tom Christie d720beadac Fixed __unicode__/__str__ for dataset with no headers 2016-02-25 13:28:29 +00:00
kennethreitz ee9666a146 Merge pull request #225 from tusharmakkar08/master
PEP-8 standards followed
2016-02-22 09:17:34 -05:00
tusharmakkar08 77a9e25795 Reverted back yaml3 for ci failure 2016-02-22 17:05:06 +05:30
tusharmakkar08 d515724817 PEP-8 standards followed 2016-02-22 16:36:26 +05:30
25 changed files with 344 additions and 321 deletions
+3
View File
@@ -26,3 +26,6 @@ junit-py27.xml
# tox noise # tox noise
.tox .tox
# pyenv noise
.python-version
+2
View File
@@ -32,3 +32,5 @@ Patches and Suggestions
- Rabin Nankhwa - Rabin Nankhwa
- Marco Dallagiacoma - Marco Dallagiacoma
- Mathias Loesch - Mathias Loesch
- Tushar Makkar
- Andrii Soldatenko
+11
View File
@@ -1,6 +1,17 @@
History History
------- -------
0.11.4 (2017-01-23)
+++++++++++++++++++
- Use built-in `json` package if available
- Support Python 3.5+ in classifiers
** Bugfixes **
- Fixed textual representation for Dataset with no headers
- Handle decimal types
0.11.3 (2016-02-16) 0.11.3 (2016-02-16)
+++++++++++++++++++ +++++++++++++++++++
+1 -1
View File
@@ -1,7 +1,7 @@
Tablib: format-agnostic tabular dataset library Tablib: format-agnostic tabular dataset library
=============================================== ===============================================
.. image:: https://travis-ci.org/kennethreitz/tablib.svg?branch=develop .. image:: https://travis-ci.org/kennethreitz/tablib.svg?branch=master
:target: https://travis-ci.org/kennethreitz/tablib :target: https://travis-ci.org/kennethreitz/tablib
:: ::
+2 -2
View File
@@ -158,9 +158,9 @@ To do so, we access the :class:`Dataset` as if it were a standard Python diction
You can also access the column using its index. :: You can also access the column using its index. ::
>>> d.headers >>> data.headers
['Last Name', 'First Name', 'Age'] ['Last Name', 'First Name', 'Age']
>>> d.get_col(1) >>> data.get_col(1)
['Kenneth', 'Bessie'] ['Kenneth', 'Bessie']
Let's find the average age. :: Let's find the average age. ::
+4 -2
View File
@@ -73,7 +73,7 @@ setup(
url='http://python-tablib.org', url='http://python-tablib.org',
packages=packages, packages=packages,
license='MIT', license='MIT',
classifiers=( classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'Natural Language :: English', 'Natural Language :: English',
@@ -87,6 +87,8 @@ setup(
'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.4',
), 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
],
tests_require=['pytest'], tests_require=['pytest'],
) )
+1
View File
@@ -34,6 +34,7 @@ if is_py3:
from io import StringIO from io import StringIO
# py3 mappings # py3 mappings
ifilter = filter
unicode = str unicode = str
bytes = bytes bytes = bytes
basestring = str basestring = str
+5 -2
View File
@@ -18,8 +18,8 @@ from tablib.compat import OrderedDict, unicode
__title__ = 'tablib' __title__ = 'tablib'
__version__ = '0.11.3' __version__ = '0.11.4'
__build__ = 0x001103 __build__ = 0x001104
__author__ = 'Kenneth Reitz' __author__ = 'Kenneth Reitz'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = 'Copyright 2016 Kenneth Reitz' __copyright__ = 'Copyright 2016 Kenneth Reitz'
@@ -143,6 +143,7 @@ class Dataset(object):
:param \*args: (optional) list of rows to populate Dataset :param \*args: (optional) list of rows to populate Dataset
:param headers: (optional) list strings for Dataset header row :param headers: (optional) list strings for Dataset header row
:param title: (optional) string to use as title of the Dataset
.. admonition:: Format Attributes Definition .. admonition:: Format Attributes Definition
@@ -223,6 +224,7 @@ class Dataset(object):
result = [] result = []
# Add unicode representation of headers. # Add unicode representation of headers.
if self.__headers:
result.append([unicode(h) for h in self.__headers]) result.append([unicode(h) for h in self.__headers])
# Add unicode representation of rows. # Add unicode representation of rows.
@@ -232,6 +234,7 @@ class Dataset(object):
field_lens = list(map(max, zip(*lens))) field_lens = list(map(max, zip(*lens)))
# delimiter between header and data # delimiter between header and data
if self.__headers:
result.insert(1, ['-' * length for length in field_lens]) result.insert(1, ['-' * length for length in field_lens])
format_string = '|'.join('{%s:%s}' % item for item in enumerate(field_lens)) format_string = '|'.join('{%s:%s}' % item for item in enumerate(field_lens))
+1
View File
@@ -55,6 +55,7 @@ def export_set(dataset):
else: else:
stream = StringIO(dbf_stream.read()) stream = StringIO(dbf_stream.read())
dbf_stream.close() dbf_stream.close()
os.close(temp_file)
os.remove(temp_uri) os.remove(temp_uri)
return stream.getvalue() return stream.getvalue()
+7 -4
View File
@@ -58,10 +58,13 @@ def export_book(databook):
stream = StringIO() stream = StringIO()
# Allow unicode characters in output
wrapper = codecs.getwriter("utf8")(stream)
for i, dset in enumerate(databook._datasets): for i, dset in enumerate(databook._datasets):
title = (dset.title if dset.title else 'Set %s' % (i)) title = (dset.title if dset.title else 'Set %s' % (i))
stream.write('<%s>%s</%s>\n' % (BOOK_ENDINGS, title, BOOK_ENDINGS)) wrapper.write('<%s>%s</%s>\n' % (BOOK_ENDINGS, title, BOOK_ENDINGS))
stream.write(dset.html) wrapper.write(dset.html)
stream.write('\n') wrapper.write('\n')
return stream.getvalue() return stream.getvalue().decode('utf-8')
+11 -2
View File
@@ -2,10 +2,13 @@
""" Tablib - JSON Support """ Tablib - JSON Support
""" """
import decimal
import tablib import tablib
import sys try:
import json
except ImportError:
from tablib.packages import omnijson as json from tablib.packages import omnijson as json
@@ -14,7 +17,13 @@ extensions = ('json', 'jsn')
def date_handler(obj): def date_handler(obj):
return obj.isoformat() if hasattr(obj, 'isoformat') else obj if isinstance(obj, decimal.Decimal):
return str(obj)
elif hasattr(obj, 'isoformat'):
return obj.isoformat()
else:
return obj
# return obj.isoformat() if hasattr(obj, 'isoformat') else obj
def export_set(dataset): def export_set(dataset):
+1 -4
View File
@@ -13,16 +13,12 @@ except ImportError:
else: else:
import tablib.packages.yaml as yaml import tablib.packages.yaml as yaml
import tablib import tablib
title = 'yaml' title = 'yaml'
extensions = ('yaml', 'yml') extensions = ('yaml', 'yml')
def export_set(dataset): def export_set(dataset):
"""Returns YAML representation of Dataset.""" """Returns YAML representation of Dataset."""
@@ -52,6 +48,7 @@ def import_book(dbook, in_stream):
data.dict = sheet['data'] data.dict = sheet['data']
dbook.add_sheet(data) dbook.add_sheet(data)
def detect(stream): def detect(stream):
"""Returns True if given stream is valid YAML.""" """Returns True if given stream is valid YAML."""
try: try:
+15 -10
View File
@@ -66,6 +66,7 @@ from . import header
from . import record from . import record
from utils import INVALID_VALUE from utils import INVALID_VALUE
class Dbf(object): class Dbf(object):
"""DBF accessor. """DBF accessor.
@@ -88,7 +89,7 @@ class Dbf(object):
RecordClass = record.DbfRecord RecordClass = record.DbfRecord
INVALID_VALUE = INVALID_VALUE INVALID_VALUE = INVALID_VALUE
## initialization and creation helpers # initialization and creation helpers
def __init__(self, f, readOnly=False, new=False, ignoreErrors=False): def __init__(self, f, readOnly=False, new=False, ignoreErrors=False):
"""Initialize instance. """Initialize instance.
@@ -137,7 +138,7 @@ class Dbf(object):
self._new = bool(new) self._new = bool(new)
self._changed = False self._changed = False
## properties # properties
closed = property(lambda self: self.stream.closed) closed = property(lambda self: self.stream.closed)
recordCount = property(lambda self: self.header.recordCount) recordCount = property(lambda self: self.header.recordCount)
@@ -149,6 +150,7 @@ class Dbf(object):
def ignoreErrors(self, value): def ignoreErrors(self, value):
"""Update `ignoreErrors` flag on the header object and self""" """Update `ignoreErrors` flag on the header object and self"""
self.header.ignoreErrors = self._ignore_errors = bool(value) self.header.ignoreErrors = self._ignore_errors = bool(value)
ignoreErrors = property( ignoreErrors = property(
lambda self: self._ignore_errors, lambda self: self._ignore_errors,
ignoreErrors, ignoreErrors,
@@ -159,7 +161,7 @@ class Dbf(object):
""") """)
## protected methods # protected methods
def _fixIndex(self, index): def _fixIndex(self, index):
"""Return fixed index. """Return fixed index.
@@ -185,7 +187,7 @@ class Dbf(object):
raise IndexError("Record index out of range") raise IndexError("Record index out of range")
return index return index
## iterface methods # iterface methods
def close(self): def close(self):
self.flush() self.flush()
@@ -228,7 +230,7 @@ class Dbf(object):
raise TypeError("At least one record was added, " raise TypeError("At least one record was added, "
"structure can't be changed") "structure can't be changed")
## 'magic' methods (representation and sequence interface) # 'magic' methods (representation and sequence interface)
def __repr__(self): def __repr__(self):
return "Dbf stream '%s'\n" % self.stream + repr(self.header) return "Dbf stream '%s'\n" % self.stream + repr(self.header)
@@ -253,14 +255,15 @@ class Dbf(object):
# self.flush() # self.flush()
def demoRead(filename): def demo_read(filename):
_dbf = Dbf(filename, True) _dbf = Dbf(filename, True)
for _rec in _dbf: for _rec in _dbf:
print print
print(repr(_rec)) print(repr(_rec))
_dbf.close() _dbf.close()
def demoCreate(filename):
def demo_create(filename):
_dbf = Dbf(filename, new=True) _dbf = Dbf(filename, new=True)
_dbf.addField( _dbf.addField(
("NAME", "C", 15), ("NAME", "C", 15),
@@ -283,10 +286,12 @@ def demoCreate(filename):
print(repr(_dbf)) print(repr(_dbf))
_dbf.close() _dbf.close()
if (__name__=='__main__'):
if __name__ == '__main__':
import sys import sys
_name = len(sys.argv) > 1 and sys.argv[1] or "county.dbf" _name = len(sys.argv) > 1 and sys.argv[1] or "county.dbf"
demoCreate(_name) demo_create(_name)
demoRead(_name) demo_read(_name)
# vim: set et sw=4 sts=4 : # vim: set et sw=4 sts=4 :
+2 -1
View File
@@ -29,6 +29,7 @@ from fields import *
from header import * from header import *
from record import * from record import *
class _FieldDefinition(object): class _FieldDefinition(object):
"""Field definition. """Field definition.
@@ -151,7 +152,7 @@ class dbf_new(object):
_dbfh.write(stream) _dbfh.write(stream)
if (__name__=='__main__'): if __name__ == '__main__':
# create a new DBF-File # create a new DBF-File
dbfn = dbf_new() dbfn = dbf_new()
dbfn.add_field("name", 'C', 80) dbfn.add_field("name", 'C', 80)
+15 -10
View File
@@ -66,6 +66,7 @@ from . import header
from . import record from . import record
from .utils import INVALID_VALUE from .utils import INVALID_VALUE
class Dbf(object): class Dbf(object):
"""DBF accessor. """DBF accessor.
@@ -88,7 +89,7 @@ class Dbf(object):
RecordClass = record.DbfRecord RecordClass = record.DbfRecord
INVALID_VALUE = INVALID_VALUE INVALID_VALUE = INVALID_VALUE
## initialization and creation helpers # initialization and creation helpers
def __init__(self, f, readOnly=False, new=False, ignoreErrors=False): def __init__(self, f, readOnly=False, new=False, ignoreErrors=False):
"""Initialize instance. """Initialize instance.
@@ -137,7 +138,7 @@ class Dbf(object):
self._new = bool(new) self._new = bool(new)
self._changed = False self._changed = False
## properties # properties
closed = property(lambda self: self.stream.closed) closed = property(lambda self: self.stream.closed)
recordCount = property(lambda self: self.header.recordCount) recordCount = property(lambda self: self.header.recordCount)
@@ -149,6 +150,7 @@ class Dbf(object):
def ignoreErrors(self, value): def ignoreErrors(self, value):
"""Update `ignoreErrors` flag on the header object and self""" """Update `ignoreErrors` flag on the header object and self"""
self.header.ignoreErrors = self._ignore_errors = bool(value) self.header.ignoreErrors = self._ignore_errors = bool(value)
ignoreErrors = property( ignoreErrors = property(
lambda self: self._ignore_errors, lambda self: self._ignore_errors,
ignoreErrors, ignoreErrors,
@@ -159,7 +161,7 @@ class Dbf(object):
""") """)
## protected methods # protected methods
def _fixIndex(self, index): def _fixIndex(self, index):
"""Return fixed index. """Return fixed index.
@@ -185,7 +187,7 @@ class Dbf(object):
raise IndexError("Record index out of range") raise IndexError("Record index out of range")
return index return index
## iterface methods # iterface methods
def close(self): def close(self):
self.flush() self.flush()
@@ -229,7 +231,7 @@ class Dbf(object):
raise TypeError("At least one record was added, " raise TypeError("At least one record was added, "
"structure can't be changed") "structure can't be changed")
## 'magic' methods (representation and sequence interface) # 'magic' methods (representation and sequence interface)
def __repr__(self): def __repr__(self):
return "Dbf stream '%s'\n" % self.stream + repr(self.header) return "Dbf stream '%s'\n" % self.stream + repr(self.header)
@@ -254,14 +256,15 @@ class Dbf(object):
# self.flush() # self.flush()
def demoRead(filename): def demo_read(filename):
_dbf = Dbf(filename, True) _dbf = Dbf(filename, True)
for _rec in _dbf: for _rec in _dbf:
print() print()
print(repr(_rec)) print(repr(_rec))
_dbf.close() _dbf.close()
def demoCreate(filename):
def demo_create(filename):
_dbf = Dbf(filename, new=True) _dbf = Dbf(filename, new=True)
_dbf.addField( _dbf.addField(
("NAME", "C", 15), ("NAME", "C", 15),
@@ -284,10 +287,12 @@ def demoCreate(filename):
print(repr(_dbf)) print(repr(_dbf))
_dbf.close() _dbf.close()
if (__name__=='__main__'):
if __name__ == '__main__':
import sys import sys
_name = len(sys.argv) > 1 and sys.argv[1] or "county.dbf" _name = len(sys.argv) > 1 and sys.argv[1] or "county.dbf"
demoCreate(_name) demo_create(_name)
demoRead(_name) demo_read(_name)
# vim: set et sw=4 sts=4 : # vim: set et sw=4 sts=4 :
+2 -1
View File
@@ -29,6 +29,7 @@ from .fields import *
from .header import * from .header import *
from .record import * from .record import *
class _FieldDefinition(object): class _FieldDefinition(object):
"""Field definition. """Field definition.
@@ -145,7 +146,7 @@ class dbf_new(object):
_dbfStream.close() _dbfStream.close()
if (__name__=='__main__'): if __name__ == '__main__':
# create a new DBF-File # create a new DBF-File
dbfn = dbf_new() dbfn = dbf_new()
dbfn.add_field("name", 'C', 80) dbfn.add_field("name", 'C', 80)
+2 -4
View File
@@ -71,10 +71,8 @@ class element:
for key, value in kwargs.iteritems( ): for key, value in kwargs.iteritems( ):
if value is not None: # when value is None that means stuff like <... checked> if value is not None: # when value is None that means stuff like <... checked>
key = key.strip('_') # strip this so class_ will mean class, etc. key = key.strip('_') # strip this so class_ will mean class, etc.
if key == 'http_equiv': # special cases, maybe change _ to - overall? if key in ['http_equiv', 'accept_charset']:
key = 'http-equiv' key.replace('_','-')
elif key == 'accept_charset':
key = 'accept-charset'
out = u"%s %s=\"%s\"" % ( out, key, escape( value ) ) out = u"%s %s=\"%s\"" % ( out, key, escape( value ) )
else: else:
out = u"%s %s" % ( out, key ) out = u"%s %s" % ( out, key )
+2 -2
View File
@@ -4,7 +4,7 @@ import sys
from antlr import EOF, CommonToken as Tok, TokenStream, TokenStreamException from antlr import EOF, CommonToken as Tok, TokenStream, TokenStreamException
import struct import struct
import ExcelFormulaParser import ExcelFormulaParser
from re import compile as recompile, match, LOCALE, UNICODE, IGNORECASE, VERBOSE from re import compile as recompile, match, UNICODE, IGNORECASE, VERBOSE
int_const_pattern = r"\d+\b" int_const_pattern = r"\d+\b"
@@ -51,7 +51,7 @@ pattern_type_tuples = (
_re = recompile( _re = recompile(
'(' + ')|('.join([i[0] for i in pattern_type_tuples]) + ')', '(' + ')|('.join([i[0] for i in pattern_type_tuples]) + ')',
VERBOSE+LOCALE+IGNORECASE) VERBOSE+IGNORECASE)
_toktype = [None] + [i[1] for i in pattern_type_tuples] _toktype = [None] + [i[1] for i in pattern_type_tuples]
# need dummy at start because re.MatchObject.lastindex counts from 1 # need dummy at start because re.MatchObject.lastindex counts from 1
+2 -2
View File
@@ -2,7 +2,7 @@ import sys
from .antlr import EOF, CommonToken as Tok, TokenStream, TokenStreamException from .antlr import EOF, CommonToken as Tok, TokenStream, TokenStreamException
import struct import struct
from . import ExcelFormulaParser from . import ExcelFormulaParser
from re import compile as recompile, match, LOCALE, UNICODE, IGNORECASE, VERBOSE from re import compile as recompile, match, UNICODE, IGNORECASE, VERBOSE
int_const_pattern = r"\d+\b" int_const_pattern = r"\d+\b"
@@ -49,7 +49,7 @@ pattern_type_tuples = (
_re = recompile( _re = recompile(
'(' + ')|('.join([i[0] for i in pattern_type_tuples]) + ')', '(' + ')|('.join([i[0] for i in pattern_type_tuples]) + ')',
VERBOSE+LOCALE+IGNORECASE) VERBOSE+IGNORECASE)
_toktype = [None] + [i[1] for i in pattern_type_tuples] _toktype = [None] + [i[1] for i in pattern_type_tuples]
# need dummy at start because re.MatchObject.lastindex counts from 1 # need dummy at start because re.MatchObject.lastindex counts from 1
+6 -7
View File
@@ -1,15 +1,16 @@
__all__ = ['Composer', 'ComposerError'] __all__ = ['Composer', 'ComposerError']
from error import MarkedYAMLError from error import MarkedYAMLError
from events import * from events import StreamEndEvent, StreamStartEvent, AliasEvent, SequenceEndEvent, SequenceStartEvent, MappingEndEvent,\
from nodes import * MappingStartEvent, ScalarEvent
from nodes import MappingNode, ScalarNode, SequenceNode
class ComposerError(MarkedYAMLError): class ComposerError(MarkedYAMLError):
pass pass
class Composer(object):
class Composer(object):
def __init__(self): def __init__(self):
self.anchors = {} self.anchors = {}
@@ -70,8 +71,7 @@ class Composer(object):
return self.anchors[anchor] return self.anchors[anchor]
event = self.peek_event() event = self.peek_event()
anchor = event.anchor anchor = event.anchor
if anchor is not None: if anchor is not None and anchor in self.anchors:
if anchor in self.anchors:
raise ComposerError("found duplicate anchor %r; first occurence" raise ComposerError("found duplicate anchor %r; first occurence"
% anchor.encode('utf-8'), self.anchors[anchor].start_mark, % anchor.encode('utf-8'), self.anchors[anchor].start_mark,
"second occurence", event.start_mark) "second occurence", event.start_mark)
@@ -136,4 +136,3 @@ class Composer(object):
end_event = self.get_event() end_event = self.get_event()
node.end_mark = end_event.end_mark node.end_mark = end_event.end_mark
return node return node
+14 -7
View File
@@ -1,4 +1,3 @@
__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor', __all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
'ConstructorError'] 'ConstructorError']
@@ -12,13 +11,17 @@ try:
except NameError: except NameError:
from sets import Set as set from sets import Set as set
import binascii, re, sys, types import binascii
import re
import sys
import types
class ConstructorError(MarkedYAMLError): class ConstructorError(MarkedYAMLError):
pass pass
class BaseConstructor(object):
class BaseConstructor(object):
yaml_constructors = {} yaml_constructors = {}
yaml_multi_constructors = {} yaml_multi_constructors = {}
@@ -155,16 +158,18 @@ class BaseConstructor(object):
if not 'yaml_constructors' in cls.__dict__: if not 'yaml_constructors' in cls.__dict__:
cls.yaml_constructors = cls.yaml_constructors.copy() cls.yaml_constructors = cls.yaml_constructors.copy()
cls.yaml_constructors[tag] = constructor cls.yaml_constructors[tag] = constructor
add_constructor = classmethod(add_constructor) add_constructor = classmethod(add_constructor)
def add_multi_constructor(cls, tag_prefix, multi_constructor): def add_multi_constructor(cls, tag_prefix, multi_constructor):
if not 'yaml_multi_constructors' in cls.__dict__: if not 'yaml_multi_constructors' in cls.__dict__:
cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy() cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy()
cls.yaml_multi_constructors[tag_prefix] = multi_constructor cls.yaml_multi_constructors[tag_prefix] = multi_constructor
add_multi_constructor = classmethod(add_multi_constructor) add_multi_constructor = classmethod(add_multi_constructor)
class SafeConstructor(BaseConstructor):
class SafeConstructor(BaseConstructor):
def construct_scalar(self, node): def construct_scalar(self, node):
if isinstance(node, MappingNode): if isinstance(node, MappingNode):
for key_node, value_node in node.value: for key_node, value_node in node.value:
@@ -418,6 +423,7 @@ class SafeConstructor(BaseConstructor):
"could not determine a constructor for the tag %r" % node.tag.encode('utf-8'), "could not determine a constructor for the tag %r" % node.tag.encode('utf-8'),
node.start_mark) node.start_mark)
SafeConstructor.add_constructor( SafeConstructor.add_constructor(
u'tag:yaml.org,2002:null', u'tag:yaml.org,2002:null',
SafeConstructor.construct_yaml_null) SafeConstructor.construct_yaml_null)
@@ -469,8 +475,8 @@ SafeConstructor.add_constructor(
SafeConstructor.add_constructor(None, SafeConstructor.add_constructor(None,
SafeConstructor.construct_undefined) SafeConstructor.construct_undefined)
class Constructor(SafeConstructor):
class Constructor(SafeConstructor):
def construct_python_str(self, node): def construct_python_str(self, node):
return self.construct_scalar(node).encode('utf-8') return self.construct_scalar(node).encode('utf-8')
@@ -538,7 +544,8 @@ class Constructor(SafeConstructor):
node.start_mark) node.start_mark)
return self.find_python_module(suffix, node.start_mark) return self.find_python_module(suffix, node.start_mark)
class classobj: pass class classobj:
pass
def make_python_instance(self, suffix, node, def make_python_instance(self, suffix, node,
args=None, kwds=None, newobj=False): args=None, kwds=None, newobj=False):
@@ -618,6 +625,7 @@ class Constructor(SafeConstructor):
def construct_python_object_new(self, suffix, node): def construct_python_object_new(self, suffix, node):
return self.construct_python_object_apply(suffix, node, newobj=True) return self.construct_python_object_apply(suffix, node, newobj=True)
Constructor.add_constructor( Constructor.add_constructor(
u'tag:yaml.org,2002:python/none', u'tag:yaml.org,2002:python/none',
Constructor.construct_yaml_null) Constructor.construct_yaml_null)
@@ -681,4 +689,3 @@ Constructor.add_multi_constructor(
Constructor.add_multi_constructor( Constructor.add_multi_constructor(
u'tag:yaml.org,2002:python/object/new:', u'tag:yaml.org,2002:python/object/new:',
Constructor.construct_python_object_new) Constructor.construct_python_object_new)
+2 -3
View File
@@ -1,15 +1,15 @@
__all__ = ['Composer', 'ComposerError'] __all__ = ['Composer', 'ComposerError']
from .error import MarkedYAMLError from .error import MarkedYAMLError
from .events import * from .events import *
from .nodes import * from .nodes import *
class ComposerError(MarkedYAMLError): class ComposerError(MarkedYAMLError):
pass pass
class Composer:
class Composer:
def __init__(self): def __init__(self):
self.anchors = {} self.anchors = {}
@@ -136,4 +136,3 @@ class Composer:
end_event = self.get_event() end_event = self.get_event()
node.end_mark = end_event.end_mark node.end_mark = end_event.end_mark
return node return node
-1
View File
@@ -683,4 +683,3 @@ Constructor.add_multi_constructor(
Constructor.add_multi_constructor( Constructor.add_multi_constructor(
'tag:yaml.org,2002:python/object/new:', 'tag:yaml.org,2002:python/object/new:',
Constructor.construct_python_object_new) Constructor.construct_python_object_new)
+32 -55
View File
@@ -6,14 +6,14 @@ import json
import unittest import unittest
import sys import sys
import os import os
import datetime
import tablib import tablib
from tablib.compat import markup, unicode, is_py3 from tablib.compat import markup, unicode, is_py3
from tablib.core import Row from tablib.core import Row
class TablibTestCase(unittest.TestCase): class TablibTestCase(unittest.TestCase):
"""Tablib test cases.""" """Tablib test cases."""
@@ -35,12 +35,10 @@ class TablibTestCase(unittest.TestCase):
self.founders.append(self.george) self.founders.append(self.george)
self.founders.append(self.tom) self.founders.append(self.tom)
def tearDown(self): def tearDown(self):
"""Teardown.""" """Teardown."""
pass pass
def test_empty_append(self): def test_empty_append(self):
"""Verify append() correctly adds tuple with no headers.""" """Verify append() correctly adds tuple with no headers."""
new_row = (1, 2, 3) new_row = (1, 2, 3)
@@ -50,7 +48,6 @@ class TablibTestCase(unittest.TestCase):
self.assertTrue(data.width == len(new_row)) self.assertTrue(data.width == len(new_row))
self.assertTrue(data[0] == new_row) self.assertTrue(data[0] == new_row)
def test_empty_append_with_headers(self): def test_empty_append_with_headers(self):
"""Verify append() correctly detects mismatch of number of """Verify append() correctly detects mismatch of number of
headers and data. headers and data.
@@ -72,7 +69,6 @@ class TablibTestCase(unittest.TestCase):
self.assertRaises(tablib.InvalidDimensions, set_header_callable) self.assertRaises(tablib.InvalidDimensions, set_header_callable)
def test_add_column(self): def test_add_column(self):
"""Verify adding column works with/without headers.""" """Verify adding column works with/without headers."""
@@ -93,7 +89,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(data['age'], new_col) self.assertEqual(data['age'], new_col)
def test_add_column_no_data_no_headers(self): def test_add_column_no_data_no_headers(self):
"""Verify adding new column with no headers.""" """Verify adding new column with no headers."""
@@ -105,7 +100,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(data.width, 1) self.assertEqual(data.width, 1)
self.assertEqual(data.height, len(new_col)) self.assertEqual(data.height, len(new_col))
def test_add_column_with_header_ignored(self): def test_add_column_with_header_ignored(self):
"""Verify append_col() ignores the header if data.headers has """Verify append_col() ignores the header if data.headers has
not previously been set not previously been set
@@ -120,7 +114,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(data.height, len(new_col)) self.assertEqual(data.height, len(new_col))
self.assertEqual(data.headers, None) self.assertEqual(data.headers, None)
def test_add_column_with_header_and_headers_only_exist(self): def test_add_column_with_header_and_headers_only_exist(self):
"""Verify append_col() with header correctly detects mismatch when """Verify append_col() with header correctly detects mismatch when
headers exist but there is no existing row data headers exist but there is no existing row data
@@ -136,7 +129,6 @@ class TablibTestCase(unittest.TestCase):
self.assertRaises(tablib.InvalidDimensions, append_col_callable) self.assertRaises(tablib.InvalidDimensions, append_col_callable)
def test_add_column_with_header_and_data_exists(self): def test_add_column_with_header_and_data_exists(self):
"""Verify append_col() works when headers and rows exists""" """Verify append_col() works when headers and rows exists"""
@@ -152,7 +144,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(data['age'], new_col) self.assertEqual(data['age'], new_col)
self.assertEqual(len(data.headers), len(self.headers) + 1) self.assertEqual(len(data.headers), len(self.headers) + 1)
def test_add_callable_column(self): def test_add_callable_column(self):
"""Verify adding column with values specified as callable.""" """Verify adding column with values specified as callable."""
@@ -160,7 +151,6 @@ class TablibTestCase(unittest.TestCase):
self.founders.append_col(new_col, header='first_again') self.founders.append_col(new_col, header='first_again')
def test_header_slicing(self): def test_header_slicing(self):
"""Verify slicing by headers.""" """Verify slicing by headers."""
@@ -173,7 +163,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(self.founders['gpa'], self.assertEqual(self.founders['gpa'],
[self.john[2], self.george[2], self.tom[2]]) [self.john[2], self.george[2], self.tom[2]])
def test_get_col(self): def test_get_col(self):
"""Verify getting columns by index""" """Verify getting columns by index"""
@@ -189,7 +178,6 @@ class TablibTestCase(unittest.TestCase):
self.founders.get_col(list(self.headers).index('gpa')), self.founders.get_col(list(self.headers).index('gpa')),
[self.john[2], self.george[2], self.tom[2]]) [self.john[2], self.george[2], self.tom[2]])
def test_data_slicing(self): def test_data_slicing(self):
"""Verify slicing by data.""" """Verify slicing by data."""
@@ -206,7 +194,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(self.founders[1:3], [self.george, self.tom]) self.assertEqual(self.founders[1:3], [self.george, self.tom])
self.assertEqual(self.founders[2:], [self.tom]) self.assertEqual(self.founders[2:], [self.tom])
def test_row_slicing(self): def test_row_slicing(self):
"""Verify Row's __getslice__ method. Issue #184.""" """Verify Row's __getslice__ method. Issue #184."""
@@ -218,7 +205,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(john[0:2], list(self.john[0:2])) self.assertEqual(john[0:2], list(self.john[0:2]))
self.assertEqual(john[0:-1], list(self.john[0:-1])) self.assertEqual(john[0:-1], list(self.john[0:-1]))
def test_delete(self): def test_delete(self):
"""Verify deleting from dataset works.""" """Verify deleting from dataset works."""
@@ -258,7 +244,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(csv, self.founders.csv) self.assertEqual(csv, self.founders.csv)
def test_tsv_export(self): def test_tsv_export(self):
"""Verify exporting dataset object as TSV.""" """Verify exporting dataset object as TSV."""
@@ -276,7 +261,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(tsv, self.founders.tsv) self.assertEqual(tsv, self.founders.tsv)
def test_html_export(self): def test_html_export(self):
"""HTML export""" """HTML export"""
@@ -288,7 +272,6 @@ class TablibTestCase(unittest.TestCase):
html.thead.close() html.thead.close()
for founder in self.founders: for founder in self.founders:
html.tr(markup.oneliner.td(founder)) html.tr(markup.oneliner.td(founder))
html.table.close() html.table.close()
@@ -296,7 +279,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(html, self.founders.html) self.assertEqual(html, self.founders.html)
def test_html_export_none_value(self): def test_html_export_none_value(self):
"""HTML export""" """HTML export"""
@@ -317,7 +299,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(html, d.html) self.assertEqual(html, d.html)
def test_latex_export(self): def test_latex_export(self):
"""LaTeX export""" """LaTeX export"""
@@ -341,17 +322,14 @@ class TablibTestCase(unittest.TestCase):
output = self.founders.latex output = self.founders.latex
self.assertEqual(output, expected) self.assertEqual(output, expected)
def test_latex_export_empty_dataset(self): def test_latex_export_empty_dataset(self):
self.assertTrue(tablib.Dataset().latex is not None) self.assertTrue(tablib.Dataset().latex is not None)
def test_latex_export_no_headers(self): def test_latex_export_no_headers(self):
d = tablib.Dataset() d = tablib.Dataset()
d.append(('one', 'two', 'three')) d.append(('one', 'two', 'three'))
self.assertTrue('one' in d.latex) self.assertTrue('one' in d.latex)
def test_latex_export_caption(self): def test_latex_export_caption(self):
d = tablib.Dataset() d = tablib.Dataset()
d.append(('one', 'two', 'three')) d.append(('one', 'two', 'three'))
@@ -360,7 +338,6 @@ class TablibTestCase(unittest.TestCase):
d.title = 'Title' d.title = 'Title'
self.assertTrue('\\caption{Title}' in d.latex) self.assertTrue('\\caption{Title}' in d.latex)
def test_latex_export_none_values(self): def test_latex_export_none_values(self):
headers = ['foo', None, 'bar'] headers = ['foo', None, 'bar']
d = tablib.Dataset(['foo', None, 'bar'], headers=headers) d = tablib.Dataset(['foo', None, 'bar'], headers=headers)
@@ -368,7 +345,6 @@ class TablibTestCase(unittest.TestCase):
self.assertTrue('foo' in output) self.assertTrue('foo' in output)
self.assertFalse('None' in output) self.assertFalse('None' in output)
def test_latex_escaping(self): def test_latex_escaping(self):
d = tablib.Dataset(['~', '^']) d = tablib.Dataset(['~', '^'])
output = d.latex output = d.latex
@@ -378,6 +354,15 @@ class TablibTestCase(unittest.TestCase):
self.assertFalse('^' in output) self.assertFalse('^' in output)
self.assertTrue('textasciicircum' in output) self.assertTrue('textasciicircum' in output)
def test_str_no_columns(self):
d = tablib.Dataset(['a', 1], ['b', 2], ['c', 3])
output = '%s' % d
self.assertEqual(output.splitlines(), [
'a|1',
'b|2',
'c|3'
])
def test_unicode_append(self): def test_unicode_append(self):
"""Passes in a single unicode character and exports.""" """Passes in a single unicode character and exports."""
@@ -387,7 +372,6 @@ class TablibTestCase(unittest.TestCase):
else: else:
exec ("new_row = (u'å', u'é')") exec ("new_row = (u'å', u'é')")
data.append(new_row) data.append(new_row)
data.json data.json
@@ -400,6 +384,25 @@ class TablibTestCase(unittest.TestCase):
data.html data.html
data.latex data.latex
def test_datetime_append(self):
"""Passes in a single datetime and a single date and exports."""
new_row = (
datetime.datetime.now(),
datetime.datetime.today(),
)
data.append(new_row)
data.json
data.yaml
data.csv
data.tsv
data.xls
data.xlsx
data.ods
data.html
data.latex
def test_book_export_no_exceptions(self): def test_book_export_no_exceptions(self):
"""Test that various exports don't error out.""" """Test that various exports don't error out."""
@@ -412,7 +415,7 @@ class TablibTestCase(unittest.TestCase):
book.xls book.xls
book.xlsx book.xlsx
book.ods book.ods
book.html
def test_json_import_set(self): def test_json_import_set(self):
"""Generate and import JSON set serialization.""" """Generate and import JSON set serialization."""
@@ -426,7 +429,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(json.loads(_json), json.loads(data.json)) self.assertEqual(json.loads(_json), json.loads(data.json))
def test_json_import_book(self): def test_json_import_book(self):
"""Generate and import JSON book serialization.""" """Generate and import JSON book serialization."""
data.append(self.john) data.append(self.john)
@@ -440,7 +442,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(json.loads(_json), json.loads(book.json)) self.assertEqual(json.loads(_json), json.loads(book.json))
def test_yaml_import_set(self): def test_yaml_import_set(self):
"""Generate and import YAML set serialization.""" """Generate and import YAML set serialization."""
data.append(self.john) data.append(self.john)
@@ -453,7 +454,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(_yaml, data.yaml) self.assertEqual(_yaml, data.yaml)
def test_yaml_import_book(self): def test_yaml_import_book(self):
"""Generate and import YAML book serialization.""" """Generate and import YAML book serialization."""
data.append(self.john) data.append(self.john)
@@ -467,7 +467,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(_yaml, book.yaml) self.assertEqual(_yaml, book.yaml)
def test_csv_import_set(self): def test_csv_import_set(self):
"""Generate and import CSV set serialization.""" """Generate and import CSV set serialization."""
data.append(self.john) data.append(self.john)
@@ -518,7 +517,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(_csv, data.get_csv(delimiter=';')) self.assertEqual(_csv, data.get_csv(delimiter=';'))
def test_csv_import_set_with_newlines(self): def test_csv_import_set_with_newlines(self):
"""Generate and import CSV set serialization when row values have """Generate and import CSV set serialization when row values have
newlines.""" newlines."""
@@ -533,7 +531,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(_csv, data.csv) self.assertEqual(_csv, data.csv)
def test_tsv_import_set(self): def test_tsv_import_set(self):
"""Generate and import TSV set serialization.""" """Generate and import TSV set serialization."""
data.append(self.john) data.append(self.john)
@@ -546,7 +543,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(_tsv, data.tsv) self.assertEqual(_tsv, data.tsv)
def test_dbf_import_set(self): def test_dbf_import_set(self):
data.append(self.john) data.append(self.john)
data.append(self.george) data.append(self.george)
@@ -664,7 +660,6 @@ class TablibTestCase(unittest.TestCase):
self.assertTrue(tablib.formats.csv.detect(_csv)) self.assertTrue(tablib.formats.csv.detect(_csv))
self.assertFalse(tablib.formats.csv.detect(_bunk)) self.assertFalse(tablib.formats.csv.detect(_bunk))
def test_tsv_format_detect(self): def test_tsv_format_detect(self):
"""Test TSV format detection.""" """Test TSV format detection."""
@@ -680,7 +675,6 @@ class TablibTestCase(unittest.TestCase):
self.assertTrue(tablib.formats.tsv.detect(_tsv)) self.assertTrue(tablib.formats.tsv.detect(_tsv))
self.assertFalse(tablib.formats.tsv.detect(_bunk)) self.assertFalse(tablib.formats.tsv.detect(_bunk))
def test_json_format_detect(self): def test_json_format_detect(self):
"""Test JSON format detection.""" """Test JSON format detection."""
@@ -692,7 +686,6 @@ class TablibTestCase(unittest.TestCase):
self.assertTrue(tablib.formats.json.detect(_json)) self.assertTrue(tablib.formats.json.detect(_json))
self.assertFalse(tablib.formats.json.detect(_bunk)) self.assertFalse(tablib.formats.json.detect(_bunk))
def test_yaml_format_detect(self): def test_yaml_format_detect(self):
"""Test YAML format detection.""" """Test YAML format detection."""
@@ -706,7 +699,6 @@ class TablibTestCase(unittest.TestCase):
self.assertFalse(tablib.formats.yaml.detect(_bunk)) self.assertFalse(tablib.formats.yaml.detect(_bunk))
self.assertFalse(tablib.formats.yaml.detect(_tsv)) self.assertFalse(tablib.formats.yaml.detect(_tsv))
def test_auto_format_detect(self): def test_auto_format_detect(self):
"""Test auto format detection.""" """Test auto format detection."""
@@ -722,7 +714,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(tablib.detect_format(_json), 'json') self.assertEqual(tablib.detect_format(_json), 'json')
self.assertEqual(tablib.detect_format(_bunk), None) self.assertEqual(tablib.detect_format(_bunk), None)
def test_transpose(self): def test_transpose(self):
"""Transpose a dataset.""" """Transpose a dataset."""
@@ -746,7 +737,6 @@ class TablibTestCase(unittest.TestCase):
data.append(('John', 'Tyler', 71)) data.append(('John', 'Tyler', 71))
self.assertEqual(data.transpose().transpose().dict, data.dict) self.assertEqual(data.transpose().transpose().dict, data.dict)
def test_row_stacking(self): def test_row_stacking(self):
"""Row stacking.""" """Row stacking."""
@@ -758,12 +748,10 @@ class TablibTestCase(unittest.TestCase):
row_stacked = self.founders.stack(to_join) row_stacked = self.founders.stack(to_join)
for column in row_stacked.headers: for column in row_stacked.headers:
original_data = self.founders[column] original_data = self.founders[column]
expected_data = original_data + original_data expected_data = original_data + original_data
self.assertEqual(row_stacked[column], expected_data) self.assertEqual(row_stacked[column], expected_data)
def test_column_stacking(self): def test_column_stacking(self):
"""Column stacking""" """Column stacking"""
@@ -775,7 +763,6 @@ class TablibTestCase(unittest.TestCase):
column_stacked = self.founders.stack_cols(to_join) column_stacked = self.founders.stack_cols(to_join)
for index, row in enumerate(column_stacked): for index, row in enumerate(column_stacked):
original_data = self.founders[index] original_data = self.founders[index]
expected_data = original_data + original_data expected_data = original_data + original_data
self.assertEqual(row, expected_data) self.assertEqual(row, expected_data)
@@ -783,7 +770,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(column_stacked[0], self.assertEqual(column_stacked[0],
("John", "Adams", 90, "John", "Adams", 90)) ("John", "Adams", 90, "John", "Adams", 90))
def test_sorting(self): def test_sorting(self):
"""Sort columns.""" """Sort columns."""
@@ -801,7 +787,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(second_row, expected_second) self.assertEqual(second_row, expected_second)
self.assertEqual(third_row, expected_third) self.assertEqual(third_row, expected_third)
def test_remove_duplicates(self): def test_remove_duplicates(self):
"""Unique Rows.""" """Unique Rows."""
@@ -820,7 +805,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(self.founders[2], self.tom) self.assertEqual(self.founders[2], self.tom)
self.assertEqual(self.founders.height, 3) self.assertEqual(self.founders.height, 3)
def test_wipe(self): def test_wipe(self):
"""Purge a dataset.""" """Purge a dataset."""
@@ -837,7 +821,6 @@ class TablibTestCase(unittest.TestCase):
self.assertTrue(data.width == len(new_row)) self.assertTrue(data.width == len(new_row))
self.assertTrue(data[0] == new_row) self.assertTrue(data[0] == new_row)
def test_subset(self): def test_subset(self):
"""Create a subset of a dataset""" """Create a subset of a dataset"""
@@ -857,7 +840,6 @@ class TablibTestCase(unittest.TestCase):
self.assertEqual(subset._data[0].list, ['John', 90]) self.assertEqual(subset._data[0].list, ['John', 90])
self.assertEqual(subset._data[1].list, ['Thomas', 50]) self.assertEqual(subset._data[1].list, ['Thomas', 50])
def test_formatters(self): def test_formatters(self):
"""Confirm formatters are being triggered.""" """Confirm formatters are being triggered."""
@@ -879,7 +861,6 @@ class TablibTestCase(unittest.TestCase):
else: else:
exec ("data.append([u'\xfc', u'\xfd'])") exec ("data.append([u'\xfc', u'\xfd'])")
data.csv data.csv
def test_csv_column_select(self): def test_csv_column_select(self):
@@ -895,7 +876,6 @@ class TablibTestCase(unittest.TestCase):
csv_first_name = data[headers[0]] csv_first_name = data[headers[0]]
self.assertEqual(orig_first_name, csv_first_name) self.assertEqual(orig_first_name, csv_first_name)
def test_csv_column_delete(self): def test_csv_column_delete(self):
"""Build up a CSV and test deleting a column""" """Build up a CSV and test deleting a column"""
@@ -929,7 +909,6 @@ class TablibTestCase(unittest.TestCase):
self.founders.append(('Old', 'Man', 100500)) self.founders.append(('Old', 'Man', 100500))
self.assertEqual('first_name|last_name |gpa ', unicode(self.founders).split('\n')[0]) self.assertEqual('first_name|last_name |gpa ', unicode(self.founders).split('\n')[0])
def test_databook_add_sheet_accepts_only_dataset_instances(self): def test_databook_add_sheet_accepts_only_dataset_instances(self):
class NotDataset(object): class NotDataset(object):
def append(self, item): def append(self, item):
@@ -940,7 +919,6 @@ class TablibTestCase(unittest.TestCase):
self.assertRaises(tablib.InvalidDatasetType, book.add_sheet, dataset) self.assertRaises(tablib.InvalidDatasetType, book.add_sheet, dataset)
def test_databook_add_sheet_accepts_dataset_subclasses(self): def test_databook_add_sheet_accepts_dataset_subclasses(self):
class DatasetSubclass(tablib.Dataset): class DatasetSubclass(tablib.Dataset):
pass pass
@@ -955,7 +933,6 @@ class TablibTestCase(unittest.TestCase):
except tablib.InvalidDatasetType: except tablib.InvalidDatasetType:
self.fail("Subclass of tablib.Dataset should be accepted by Databook.add_sheet") self.fail("Subclass of tablib.Dataset should be accepted by Databook.add_sheet")
def test_csv_formatter_support_kwargs(self): def test_csv_formatter_support_kwargs(self):
"""Test CSV import and export with formatter configuration.""" """Test CSV import and export with formatter configuration."""
data.append(self.john) data.append(self.john)
+1 -1
View File
@@ -4,7 +4,7 @@
# and then run "tox" from this directory. # and then run "tox" from this directory.
[tox] [tox]
envlist = py26, py27, py32, py33, py34, pypy envlist = py26, py27, py32, py33, py34, py35, py36, pypy
[testenv] [testenv]
commands = python setup.py test commands = python setup.py test