mirror of
https://github.com/kennethreitz/tablib.git
synced 2026-06-05 23:10:17 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c66697280 | |||
| 13334b7996 | |||
| 77a5c8d3fb | |||
| 79d66cd250 | |||
| 77469ef655 | |||
| e21676d3bd | |||
| 7c59e1ae86 |
@@ -26,6 +26,3 @@ junit-py27.xml
|
|||||||
|
|
||||||
# tox noise
|
# tox noise
|
||||||
.tox
|
.tox
|
||||||
|
|
||||||
# pyenv noise
|
|
||||||
.python-version
|
|
||||||
|
|||||||
@@ -32,5 +32,3 @@ Patches and Suggestions
|
|||||||
- Rabin Nankhwa
|
- Rabin Nankhwa
|
||||||
- Marco Dallagiacoma
|
- Marco Dallagiacoma
|
||||||
- Mathias Loesch
|
- Mathias Loesch
|
||||||
- Tushar Makkar
|
|
||||||
- Andrii Soldatenko
|
|
||||||
|
|||||||
-11
@@ -1,17 +1,6 @@
|
|||||||
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
@@ -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=master
|
.. image:: https://travis-ci.org/kennethreitz/tablib.svg?branch=develop
|
||||||
:target: https://travis-ci.org/kennethreitz/tablib
|
:target: https://travis-ci.org/kennethreitz/tablib
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ Once installed, we can generate our xUnit report with a single command. ::
|
|||||||
|
|
||||||
This will generate a **nosetests.xml** file, which can then be analyzed.
|
This will generate a **nosetests.xml** file, which can then be analyzed.
|
||||||
|
|
||||||
.. _Nose: http://somethingaboutorange.com/mrl/projects/nose/
|
.. _Nose: https://github.com/nose-devs/nose
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -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. ::
|
||||||
|
|
||||||
>>> data.headers
|
>>> d.headers
|
||||||
['Last Name', 'First Name', 'Age']
|
['Last Name', 'First Name', 'Age']
|
||||||
>>> data.get_col(1)
|
>>> d.get_col(1)
|
||||||
['Kenneth', 'Bessie']
|
['Kenneth', 'Bessie']
|
||||||
|
|
||||||
Let's find the average age. ::
|
Let's find the average age. ::
|
||||||
|
|||||||
@@ -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,8 +87,6 @@ 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'],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ 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
|
||||||
|
|||||||
+3
-6
@@ -18,8 +18,8 @@ from tablib.compat import OrderedDict, unicode
|
|||||||
|
|
||||||
|
|
||||||
__title__ = 'tablib'
|
__title__ = 'tablib'
|
||||||
__version__ = '0.11.4'
|
__version__ = '0.11.3'
|
||||||
__build__ = 0x001104
|
__build__ = 0x001103
|
||||||
__author__ = 'Kenneth Reitz'
|
__author__ = 'Kenneth Reitz'
|
||||||
__license__ = 'MIT'
|
__license__ = 'MIT'
|
||||||
__copyright__ = 'Copyright 2016 Kenneth Reitz'
|
__copyright__ = 'Copyright 2016 Kenneth Reitz'
|
||||||
@@ -143,7 +143,6 @@ 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
|
||||||
@@ -224,7 +223,6 @@ 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.
|
||||||
@@ -234,7 +232,6 @@ 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))
|
||||||
@@ -1108,7 +1105,7 @@ class Databook(object):
|
|||||||
"""The number of the :class:`Dataset` objects within :class:`Databook`."""
|
"""The number of the :class:`Dataset` objects within :class:`Databook`."""
|
||||||
return len(self._datasets)
|
return len(self._datasets)
|
||||||
|
|
||||||
def load(self, format, in_stream, **kwargs):
|
def load(self, in_stream, format, **kwargs):
|
||||||
"""
|
"""
|
||||||
Import `in_stream` to the :class:`Databook` object using the `format`.
|
Import `in_stream` to the :class:`Databook` object using the `format`.
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ 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()
|
||||||
|
|
||||||
|
|||||||
@@ -58,13 +58,10 @@ 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))
|
||||||
wrapper.write('<%s>%s</%s>\n' % (BOOK_ENDINGS, title, BOOK_ENDINGS))
|
stream.write('<%s>%s</%s>\n' % (BOOK_ENDINGS, title, BOOK_ENDINGS))
|
||||||
wrapper.write(dset.html)
|
stream.write(dset.html)
|
||||||
wrapper.write('\n')
|
stream.write('\n')
|
||||||
|
|
||||||
return stream.getvalue().decode('utf-8')
|
return stream.getvalue()
|
||||||
|
|||||||
+2
-11
@@ -2,13 +2,10 @@
|
|||||||
|
|
||||||
""" Tablib - JSON Support
|
""" Tablib - JSON Support
|
||||||
"""
|
"""
|
||||||
import decimal
|
|
||||||
|
|
||||||
import tablib
|
import tablib
|
||||||
|
|
||||||
try:
|
import sys
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
from tablib.packages import omnijson as json
|
from tablib.packages import omnijson as json
|
||||||
|
|
||||||
|
|
||||||
@@ -17,13 +14,7 @@ extensions = ('json', 'jsn')
|
|||||||
|
|
||||||
|
|
||||||
def date_handler(obj):
|
def date_handler(obj):
|
||||||
if isinstance(obj, decimal.Decimal):
|
return obj.isoformat() if hasattr(obj, 'isoformat') else obj
|
||||||
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):
|
||||||
|
|||||||
+10
-12
@@ -17,6 +17,7 @@ import tablib
|
|||||||
Workbook = openpyxl.workbook.Workbook
|
Workbook = openpyxl.workbook.Workbook
|
||||||
ExcelWriter = openpyxl.writer.excel.ExcelWriter
|
ExcelWriter = openpyxl.writer.excel.ExcelWriter
|
||||||
get_column_letter = openpyxl.cell.get_column_letter
|
get_column_letter = openpyxl.cell.get_column_letter
|
||||||
|
DataTypeException = openpyxl.shared.exc.DataTypeException
|
||||||
|
|
||||||
from tablib.compat import unicode
|
from tablib.compat import unicode
|
||||||
|
|
||||||
@@ -120,7 +121,6 @@ def dset_sheet(dataset, ws, freeze_panes=True):
|
|||||||
if (row_number == 1) and dataset.headers:
|
if (row_number == 1) and dataset.headers:
|
||||||
# ws.cell('%s%s'%(col_idx, row_number)).value = unicode(
|
# ws.cell('%s%s'%(col_idx, row_number)).value = unicode(
|
||||||
# '%s' % col, errors='ignore')
|
# '%s' % col, errors='ignore')
|
||||||
ws.cell('%s%s'%(col_idx, row_number)).value = unicode(col)
|
|
||||||
style = ws.get_style('%s%s' % (col_idx, row_number))
|
style = ws.get_style('%s%s' % (col_idx, row_number))
|
||||||
style.font.bold = True
|
style.font.bold = True
|
||||||
if freeze_panes:
|
if freeze_panes:
|
||||||
@@ -130,23 +130,21 @@ def dset_sheet(dataset, ws, freeze_panes=True):
|
|||||||
|
|
||||||
# bold separators
|
# bold separators
|
||||||
elif len(row) < dataset.width:
|
elif len(row) < dataset.width:
|
||||||
ws.cell('%s%s'%(col_idx, row_number)).value = unicode(
|
|
||||||
'%s' % col, errors='ignore')
|
|
||||||
style = ws.get_style('%s%s' % (col_idx, row_number))
|
style = ws.get_style('%s%s' % (col_idx, row_number))
|
||||||
style.font.bold = True
|
style.font.bold = True
|
||||||
|
|
||||||
# wrap the rest
|
# wrap the rest
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
if '\n' in col:
|
str_col_value = unicode(col)
|
||||||
ws.cell('%s%s'%(col_idx, row_number)).value = unicode(
|
except TypeError:
|
||||||
'%s' % col, errors='ignore')
|
str_col_value = ''
|
||||||
|
|
||||||
|
if '\n' in str_col_value:
|
||||||
style = ws.get_style('%s%s' % (col_idx, row_number))
|
style = ws.get_style('%s%s' % (col_idx, row_number))
|
||||||
style.alignment.wrap_text
|
style.alignment.wrap_text
|
||||||
else:
|
|
||||||
ws.cell('%s%s'%(col_idx, row_number)).value = unicode(
|
try:
|
||||||
'%s' % col, errors='ignore')
|
ws.cell('%s%s' % (col_idx, row_number)).value = col
|
||||||
except TypeError:
|
except (ValueError, TypeError, DataTypeException):
|
||||||
ws.cell('%s%s' % (col_idx, row_number)).value = unicode(col)
|
ws.cell('%s%s' % (col_idx, row_number)).value = unicode(col)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,16 @@ 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."""
|
||||||
|
|
||||||
@@ -48,7 +52,6 @@ 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:
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ 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.
|
||||||
|
|
||||||
@@ -89,7 +88,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.
|
||||||
@@ -138,7 +137,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)
|
||||||
@@ -150,7 +149,6 @@ 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,
|
||||||
@@ -161,7 +159,7 @@ class Dbf(object):
|
|||||||
|
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# protected methods
|
## protected methods
|
||||||
|
|
||||||
def _fixIndex(self, index):
|
def _fixIndex(self, index):
|
||||||
"""Return fixed index.
|
"""Return fixed index.
|
||||||
@@ -187,7 +185,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()
|
||||||
@@ -230,7 +228,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)
|
||||||
@@ -255,15 +253,14 @@ class Dbf(object):
|
|||||||
# self.flush()
|
# self.flush()
|
||||||
|
|
||||||
|
|
||||||
def demo_read(filename):
|
def demoRead(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),
|
||||||
@@ -286,12 +283,10 @@ def demo_create(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"
|
||||||
demo_create(_name)
|
demoCreate(_name)
|
||||||
demo_read(_name)
|
demoRead(_name)
|
||||||
|
|
||||||
# vim: set et sw=4 sts=4 :
|
# vim: set et sw=4 sts=4 :
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ 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.
|
||||||
|
|
||||||
@@ -152,7 +151,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)
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ 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.
|
||||||
|
|
||||||
@@ -89,7 +88,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.
|
||||||
@@ -138,7 +137,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)
|
||||||
@@ -150,7 +149,6 @@ 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,
|
||||||
@@ -161,7 +159,7 @@ class Dbf(object):
|
|||||||
|
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# protected methods
|
## protected methods
|
||||||
|
|
||||||
def _fixIndex(self, index):
|
def _fixIndex(self, index):
|
||||||
"""Return fixed index.
|
"""Return fixed index.
|
||||||
@@ -187,7 +185,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()
|
||||||
@@ -231,7 +229,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)
|
||||||
@@ -256,15 +254,14 @@ class Dbf(object):
|
|||||||
# self.flush()
|
# self.flush()
|
||||||
|
|
||||||
|
|
||||||
def demo_read(filename):
|
def demoRead(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),
|
||||||
@@ -287,12 +284,10 @@ def demo_create(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"
|
||||||
demo_create(_name)
|
demoCreate(_name)
|
||||||
demo_read(_name)
|
demoRead(_name)
|
||||||
|
|
||||||
# vim: set et sw=4 sts=4 :
|
# vim: set et sw=4 sts=4 :
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ 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.
|
||||||
|
|
||||||
@@ -146,7 +145,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)
|
||||||
|
|||||||
@@ -71,8 +71,10 @@ 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 in ['http_equiv', 'accept_charset']:
|
if key == 'http_equiv': # special cases, maybe change _ to - overall?
|
||||||
key.replace('_','-')
|
key = 'http-equiv'
|
||||||
|
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 )
|
||||||
|
|||||||
@@ -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, UNICODE, IGNORECASE, VERBOSE
|
from re import compile as recompile, match, LOCALE, 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+IGNORECASE)
|
VERBOSE+LOCALE+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,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, UNICODE, IGNORECASE, VERBOSE
|
from re import compile as recompile, match, LOCALE, 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+IGNORECASE)
|
VERBOSE+LOCALE+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
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
|
|
||||||
__all__ = ['Composer', 'ComposerError']
|
__all__ = ['Composer', 'ComposerError']
|
||||||
|
|
||||||
from error import MarkedYAMLError
|
from error import MarkedYAMLError
|
||||||
from events import StreamEndEvent, StreamStartEvent, AliasEvent, SequenceEndEvent, SequenceStartEvent, MappingEndEvent,\
|
from events import *
|
||||||
MappingStartEvent, ScalarEvent
|
from nodes import *
|
||||||
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 = {}
|
||||||
|
|
||||||
@@ -71,7 +70,8 @@ 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 and anchor in self.anchors:
|
if anchor is not None:
|
||||||
|
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,3 +136,4 @@ 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
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
|
__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
|
||||||
'ConstructorError']
|
'ConstructorError']
|
||||||
|
|
||||||
@@ -11,17 +12,13 @@ try:
|
|||||||
except NameError:
|
except NameError:
|
||||||
from sets import Set as set
|
from sets import Set as set
|
||||||
|
|
||||||
import binascii
|
import binascii, re, sys, types
|
||||||
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 = {}
|
||||||
|
|
||||||
@@ -158,18 +155,16 @@ 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:
|
||||||
@@ -423,7 +418,6 @@ 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)
|
||||||
@@ -475,8 +469,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')
|
||||||
|
|
||||||
@@ -544,8 +538,7 @@ 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:
|
class classobj: pass
|
||||||
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):
|
||||||
@@ -625,7 +618,6 @@ 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)
|
||||||
@@ -689,3 +681,4 @@ 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)
|
||||||
|
|
||||||
|
|||||||
@@ -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,3 +136,4 @@ 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
|
||||||
|
|
||||||
|
|||||||
@@ -683,3 +683,4 @@ 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)
|
||||||
|
|
||||||
|
|||||||
+55
-32
@@ -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,10 +35,12 @@ 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)
|
||||||
@@ -48,6 +50,7 @@ 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.
|
||||||
@@ -69,6 +72,7 @@ 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."""
|
||||||
|
|
||||||
@@ -89,6 +93,7 @@ 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."""
|
||||||
|
|
||||||
@@ -100,6 +105,7 @@ 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
|
||||||
@@ -114,6 +120,7 @@ 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
|
||||||
@@ -129,6 +136,7 @@ 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"""
|
||||||
|
|
||||||
@@ -144,6 +152,7 @@ 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."""
|
||||||
|
|
||||||
@@ -151,6 +160,7 @@ 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."""
|
||||||
|
|
||||||
@@ -163,6 +173,7 @@ 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"""
|
||||||
|
|
||||||
@@ -178,6 +189,7 @@ 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."""
|
||||||
|
|
||||||
@@ -194,6 +206,7 @@ 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."""
|
||||||
|
|
||||||
@@ -205,6 +218,7 @@ 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."""
|
||||||
|
|
||||||
@@ -244,6 +258,7 @@ 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."""
|
||||||
|
|
||||||
@@ -261,6 +276,7 @@ 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"""
|
||||||
|
|
||||||
@@ -272,6 +288,7 @@ 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()
|
||||||
@@ -279,6 +296,7 @@ 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"""
|
||||||
|
|
||||||
@@ -299,6 +317,7 @@ 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"""
|
||||||
|
|
||||||
@@ -322,14 +341,17 @@ 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'))
|
||||||
@@ -338,6 +360,7 @@ 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)
|
||||||
@@ -345,6 +368,7 @@ 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
|
||||||
@@ -354,15 +378,6 @@ 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."""
|
||||||
@@ -372,25 +387,6 @@ class TablibTestCase(unittest.TestCase):
|
|||||||
else:
|
else:
|
||||||
exec("new_row = (u'å', u'é')")
|
exec("new_row = (u'å', u'é')")
|
||||||
|
|
||||||
data.append(new_row)
|
|
||||||
|
|
||||||
data.json
|
|
||||||
data.yaml
|
|
||||||
data.csv
|
|
||||||
data.tsv
|
|
||||||
data.xls
|
|
||||||
data.xlsx
|
|
||||||
data.ods
|
|
||||||
data.html
|
|
||||||
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.append(new_row)
|
||||||
|
|
||||||
@@ -404,6 +400,7 @@ class TablibTestCase(unittest.TestCase):
|
|||||||
data.html
|
data.html
|
||||||
data.latex
|
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."""
|
||||||
|
|
||||||
@@ -415,7 +412,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."""
|
||||||
@@ -429,6 +426,7 @@ 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)
|
||||||
@@ -442,6 +440,7 @@ 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)
|
||||||
@@ -454,6 +453,7 @@ 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,6 +467,7 @@ 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)
|
||||||
@@ -517,6 +518,7 @@ 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."""
|
||||||
@@ -531,6 +533,7 @@ 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)
|
||||||
@@ -543,6 +546,7 @@ 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)
|
||||||
@@ -660,6 +664,7 @@ 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."""
|
||||||
|
|
||||||
@@ -675,6 +680,7 @@ 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."""
|
||||||
|
|
||||||
@@ -686,6 +692,7 @@ 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."""
|
||||||
|
|
||||||
@@ -699,6 +706,7 @@ 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."""
|
||||||
|
|
||||||
@@ -714,6 +722,7 @@ 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."""
|
||||||
|
|
||||||
@@ -737,6 +746,7 @@ 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."""
|
||||||
|
|
||||||
@@ -748,10 +758,12 @@ 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"""
|
||||||
|
|
||||||
@@ -763,6 +775,7 @@ 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)
|
||||||
@@ -770,6 +783,7 @@ 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."""
|
||||||
|
|
||||||
@@ -787,6 +801,7 @@ 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."""
|
||||||
|
|
||||||
@@ -805,6 +820,7 @@ 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."""
|
||||||
|
|
||||||
@@ -821,6 +837,7 @@ 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"""
|
||||||
|
|
||||||
@@ -840,6 +857,7 @@ 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."""
|
||||||
|
|
||||||
@@ -861,6 +879,7 @@ 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):
|
||||||
@@ -876,6 +895,7 @@ 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"""
|
||||||
|
|
||||||
@@ -909,6 +929,7 @@ 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):
|
||||||
@@ -919,6 +940,7 @@ 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
|
||||||
@@ -933,6 +955,7 @@ 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)
|
||||||
|
|||||||
@@ -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, py35, py36, pypy
|
envlist = py26, py27, py32, py33, py34, pypy
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
commands = python setup.py test
|
commands = python setup.py test
|
||||||
|
|||||||
Reference in New Issue
Block a user