mirror of
https://github.com/kennethreitz/tablib.git
synced 2026-06-05 15:00:19 +00:00
Compare commits
104 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6407afba3e | |||
| 7aada68952 | |||
| 5ba92b0f6b | |||
| 9f26c23eb5 | |||
| 8136f4b09e | |||
| 7e7ad73ddd | |||
| f889910629 | |||
| 969d9d957d | |||
| 86d84b555d | |||
| 66867527d2 | |||
| 7505d8d985 | |||
| d5515c17b8 | |||
| 07ac723971 | |||
| 5d7843ea59 | |||
| b5f0cf9d37 | |||
| a73bbe1645 | |||
| f1bdf43aab | |||
| 7623bfe7b0 | |||
| 59ccc0b422 | |||
| 99154aa6d6 | |||
| 65836d5ace | |||
| 4117503ed5 | |||
| dfa26a7d53 | |||
| 4f035caf1b | |||
| a9c7a5067d | |||
| 80cb42e8dd | |||
| 8d7e5732cd | |||
| 942dd3dadf | |||
| b1d282744c | |||
| 4c0c879d65 | |||
| cab63e02c8 | |||
| 63d025888a | |||
| 5a993ac281 | |||
| 666dd1d2c7 | |||
| ac1666e3ae | |||
| 5b7e817db2 | |||
| f9c168e4bc | |||
| 82f3d84c7d | |||
| 121cf46aec | |||
| 4bb4a05bcb | |||
| e52b8dd329 | |||
| 93fb89b8b6 | |||
| c01b66a16a | |||
| c3fa29a166 | |||
| 8d6a52aaf5 | |||
| 703b1da04c | |||
| 0e6bd079cc | |||
| 579dbf0cc0 | |||
| fbabb430ca | |||
| b8f923f8c5 | |||
| fbe6fe1612 | |||
| 17e90e71e5 | |||
| dc21825f34 | |||
| 7364995eaa | |||
| 3407170b99 | |||
| dd13744c92 | |||
| 31e4c39762 | |||
| 4fc70957ac | |||
| 7f17ccf445 | |||
| fbcc3b60af | |||
| 9b3268f0ad | |||
| f386ef8ac8 | |||
| e8f5e023c4 | |||
| 81445aeec8 | |||
| f94a236122 | |||
| bfbb7c626f | |||
| be0f77f9ee | |||
| 3b44349090 | |||
| 04a16afa58 | |||
| a8632125dc | |||
| ccf2ebcde2 | |||
| 2c60ce9233 | |||
| 649c7e8bb7 | |||
| 2d3dc5ef71 | |||
| efc516f366 | |||
| b2a51fd941 | |||
| d54d70bc22 | |||
| 391ad61bef | |||
| 99a45814d1 | |||
| fad3546614 | |||
| 7ba2849829 | |||
| 7ec0f2ef07 | |||
| bd470684a4 | |||
| dbcea81c17 | |||
| 49dc4a249e | |||
| 7cd82f956f | |||
| 13c3e537fd | |||
| f913853cae | |||
| ea1de420a3 | |||
| d0c8df95a3 | |||
| bb4e97f8aa | |||
| ffaeb64639 | |||
| f31ec562b4 | |||
| 68d7204b2d | |||
| 52db1ddc3e | |||
| 4755020dd7 | |||
| 5468dd7e67 | |||
| 8673710ddb | |||
| f01cf184d4 | |||
| 1482ca4a19 | |||
| 93c6c39581 | |||
| a0cb44cc43 | |||
| b2cd061773 | |||
| 876b849950 |
+4
-2
@@ -4,8 +4,8 @@ dist/*
|
|||||||
MANIFEST
|
MANIFEST
|
||||||
|
|
||||||
# python skin
|
# python skin
|
||||||
.pyc
|
*.pyc
|
||||||
.pyo
|
*.pyo
|
||||||
|
|
||||||
# osx noise
|
# osx noise
|
||||||
.DS_Store
|
.DS_Store
|
||||||
@@ -15,3 +15,5 @@ profile
|
|||||||
.idea
|
.idea
|
||||||
.idea/*
|
.idea/*
|
||||||
|
|
||||||
|
# vi noise
|
||||||
|
*.swp
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ Development Lead
|
|||||||
Patches and Suggestions
|
Patches and Suggestions
|
||||||
```````````````````````
|
```````````````````````
|
||||||
|
|
||||||
- A Lucky Someone
|
- Luke Lee
|
||||||
+40
@@ -1,6 +1,46 @@
|
|||||||
History
|
History
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
0.8.1 (2010-09-28)
|
||||||
|
------------------
|
||||||
|
* Packaging Fix
|
||||||
|
|
||||||
|
|
||||||
|
0.8.0 (2010-09-25)
|
||||||
|
------------------
|
||||||
|
* New format plugin system!
|
||||||
|
* Imports! ELEGANT Imports!
|
||||||
|
* Tests. Lots of tests.
|
||||||
|
|
||||||
|
|
||||||
|
0.7.1 (2010-09-20)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Reverting methods back to properties.
|
||||||
|
* Windows bug compenated in documentation.
|
||||||
|
|
||||||
|
|
||||||
|
0.7.0 (2010-09-20)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Renamed DataBook Databook for consistiency.
|
||||||
|
* Export properties changed to methods (XLS filename / StringIO bug).
|
||||||
|
* Optional Dataset.xls(path='filename') support (for writing on windows).
|
||||||
|
* Added utf-8 on the worksheet level.
|
||||||
|
|
||||||
|
|
||||||
|
0.6.4 (2010-09-19)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Updated unicode export for XLS.
|
||||||
|
* More exhaustive unit tests.
|
||||||
|
|
||||||
|
|
||||||
|
0.6.3 (2010-09-14)
|
||||||
|
------------------
|
||||||
|
* Added Dataset.append() support for columns.
|
||||||
|
|
||||||
|
|
||||||
0.6.2 (2010-09-13)
|
0.6.2 (2010-09-13)
|
||||||
------------------
|
------------------
|
||||||
* Fixed Dataset.append() error on empty dataset.
|
* Fixed Dataset.append() error on empty dataset.
|
||||||
|
|||||||
+67
-18
@@ -15,15 +15,27 @@ Tablib is a format-agnostic tabular dataset library, written in Python.
|
|||||||
|
|
||||||
Output formats supported:
|
Output formats supported:
|
||||||
|
|
||||||
- Excel
|
- Excel (Sets + Books)
|
||||||
- JSON
|
- JSON (Sets + Books)
|
||||||
- YAML
|
- YAML (Sets + Books)
|
||||||
- CSV
|
- CSV (Sets)
|
||||||
|
|
||||||
At this time, Tablib supports the **export** of it's powerful Dataset object instances into any of the above formats. Import is underway.
|
Import formats supported:
|
||||||
|
|
||||||
|
- JSON (Sets + Books)
|
||||||
|
- YAML (Sets + Books)
|
||||||
|
- CSV (Sets)
|
||||||
|
|
||||||
Note that tablib *purposefully* excludes XML support. It always will.
|
Note that tablib *purposefully* excludes XML support. It always will.
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
`tablib.Dataset()`
|
||||||
|
A Dataset is a table of tabular data. It may or may not have a header row. They can be build and maniuplated as raw Python datatypes (Lists of tuples|dictonaries). Datasets can be imported from JSON, YAML, and CSV; they can be exported to Excel (XLS), JSON, YAML, and CSV.
|
||||||
|
|
||||||
|
`tablib.Databook()`
|
||||||
|
A Databook is a set of Datasets. The most common form of a Databook is an Excel file with multiple spreadsheets. Databooks can be imported from JSON and YAML; they can be exported to Excel (XLS), JSON, and YAML.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
@@ -31,11 +43,11 @@ Usage
|
|||||||
|
|
||||||
Populate fresh data files: ::
|
Populate fresh data files: ::
|
||||||
|
|
||||||
headers = ('first_name', 'last_name', 'gpa')
|
headers = ('first_name', 'last_name')
|
||||||
|
|
||||||
data = [
|
data = [
|
||||||
('John', 'Adams', 90),
|
('John', 'Adams'),
|
||||||
('George', 'Washington', 67)
|
('George', 'Washington')
|
||||||
]
|
]
|
||||||
|
|
||||||
data = tablib.Dataset(*data, headers=headers)
|
data = tablib.Dataset(*data, headers=headers)
|
||||||
@@ -43,7 +55,11 @@ Populate fresh data files: ::
|
|||||||
|
|
||||||
Intelligently add new rows: ::
|
Intelligently add new rows: ::
|
||||||
|
|
||||||
>>> data.append(('Henry', 'Ford', 83))
|
>>> data.append(('Henry', 'Ford'))
|
||||||
|
|
||||||
|
Intelligently add new columns: ::
|
||||||
|
|
||||||
|
>>> data.append(col=('age', 90, 67, 83))
|
||||||
|
|
||||||
Slice rows: ::
|
Slice rows: ::
|
||||||
|
|
||||||
@@ -60,6 +76,9 @@ Easily delete rows: ::
|
|||||||
|
|
||||||
>>> del data[1]
|
>>> del data[1]
|
||||||
|
|
||||||
|
Exports
|
||||||
|
-------
|
||||||
|
|
||||||
Drumroll please...........
|
Drumroll please...........
|
||||||
|
|
||||||
JSON!
|
JSON!
|
||||||
@@ -102,11 +121,44 @@ EXCEL!
|
|||||||
++++++
|
++++++
|
||||||
::
|
::
|
||||||
|
|
||||||
>>> open('people.xls').write(data.xls)
|
>>> open('people.xls', 'wb').write(data.xls)
|
||||||
|
|
||||||
It's that easy.
|
It's that easy.
|
||||||
|
|
||||||
|
Imports!
|
||||||
|
--------
|
||||||
|
|
||||||
|
JSON
|
||||||
|
++++
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
>>> data.json = '[{"last_name": "Adams","age": 90,"first_name": "John"}]'
|
||||||
|
>>> print data[0]
|
||||||
|
('John', 'Adams', 90)
|
||||||
|
|
||||||
|
|
||||||
|
YAML
|
||||||
|
++++
|
||||||
|
::
|
||||||
|
|
||||||
|
>>> data.yaml = '- {age: 90, first_name: John, last_name: Adams}'
|
||||||
|
>>> print data[0]
|
||||||
|
('John', 'Adams', 90)
|
||||||
|
|
||||||
|
CSV
|
||||||
|
+++
|
||||||
|
::
|
||||||
|
|
||||||
|
>>> data.yaml = 'age, first_name, last_name\n90, John, Adams'
|
||||||
|
>>> print data[0]
|
||||||
|
('John', 'Adams', 90)
|
||||||
|
|
||||||
|
>>> print data.yaml
|
||||||
|
- {age: 90, first_name: John, last_name: Adams}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@@ -122,18 +174,15 @@ Or, if you absolutely must: ::
|
|||||||
Contribute
|
Contribute
|
||||||
----------
|
----------
|
||||||
|
|
||||||
If you'd like to contribute, simply fork `the repository`_, commit your changes, and send a pull request. Make sure you add yourself to AUTHORS_.
|
If you'd like to contribute, simply fork `the repository`_, commit your changes to the **develop** branch (or branch off of it), and send a pull request. Make sure you add yourself to AUTHORS_.
|
||||||
|
|
||||||
|
|
||||||
Roadmap
|
Roadmap
|
||||||
-------
|
-------
|
||||||
- Add ability to add/remove full columns
|
|
||||||
- Import datasets from CSV, JSON, YAML
|
|
||||||
- Release CLI Interface
|
- Release CLI Interface
|
||||||
- Auto-detect import format
|
- Auto-detect import format
|
||||||
- Add possible other exports (SQL?)
|
- Add possible other exports (SQL?)
|
||||||
- Possibly plugin-ify format architecture
|
- Ability to assign types to rows (set, regex=, &c.)
|
||||||
- Plugin support
|
|
||||||
|
|
||||||
.. _`the repository`: http://github.com/kennethreitz/tablib
|
.. _`the repository`: http://github.com/kennethreitz/tablib
|
||||||
.. _AUTHORS: http://github.com/kennethreitz/tablib/blob/master/AUTHORS
|
.. _AUTHORS: http://github.com/kennethreitz/tablib/blob/master/AUTHORS
|
||||||
|
|||||||
@@ -11,21 +11,20 @@ def publish():
|
|||||||
"""Publish to PyPi"""
|
"""Publish to PyPi"""
|
||||||
os.system("python setup.py sdist upload")
|
os.system("python setup.py sdist upload")
|
||||||
|
|
||||||
|
|
||||||
if sys.argv[-1] == "publish":
|
if sys.argv[-1] == "publish":
|
||||||
publish()
|
publish()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='tablib',
|
name='tablib',
|
||||||
version='0.6.2',
|
version='0.8.1',
|
||||||
description='Format agnostic tabular data library (XLS, JSON, YAML, CSV)',
|
description='Format agnostic tabular data library (XLS, JSON, YAML, CSV)',
|
||||||
long_description=open('README.rst').read() + '\n\n' +
|
long_description=open('README.rst').read() + '\n\n' +
|
||||||
open('HISTORY.rst').read(),
|
open('HISTORY.rst').read(),
|
||||||
author='Kenneth Reitz',
|
author='Kenneth Reitz',
|
||||||
author_email='me@kennethreitz.com',
|
author_email='me@kennethreitz.com',
|
||||||
url='http://github.com/kennethreitz/tablib',
|
url='http://github.com/kennethreitz/tablib',
|
||||||
packages=['tablib'],
|
packages=['tablib', 'tablib.formats'],
|
||||||
install_requires=['xlwt', 'simplejson', 'PyYAML'],
|
install_requires=['xlwt', 'simplejson', 'PyYAML'],
|
||||||
license='MIT',
|
license='MIT',
|
||||||
classifiers=(
|
classifiers=(
|
||||||
|
|||||||
+8
-1
@@ -1 +1,8 @@
|
|||||||
from core import *
|
""" Tablib.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from tablib.core import (
|
||||||
|
Databook, Dataset, InvalidDatasetType,
|
||||||
|
InvalidDimensions, UnsupportedFormat
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
+120
-108
@@ -1,28 +1,14 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# _____ ______ ______ _________
|
""" Tablib - Core Library.
|
||||||
# __ /_______ ____ /_ ___ /_ _____ ______ /
|
"""
|
||||||
# _ __/_ __ `/__ __ \__ __ \_ _ \_ __ /
|
|
||||||
# / /_ / /_/ / _ /_/ /_ /_/ // __// /_/ /
|
from tablib.formats import FORMATS as formats
|
||||||
# \__/ \__,_/ /_.___/ /_.___/ \___/ \__,_/
|
|
||||||
|
|
||||||
|
|
||||||
import csv
|
__title__ = 'tablib'
|
||||||
import cStringIO
|
__version__ = '0.8.1'
|
||||||
import random
|
__build__ = 0x000801
|
||||||
|
|
||||||
import simplejson as json
|
|
||||||
import xlwt
|
|
||||||
import yaml
|
|
||||||
|
|
||||||
from helpers import *
|
|
||||||
|
|
||||||
|
|
||||||
# __all__ = ['Dataset', 'DataBook']
|
|
||||||
|
|
||||||
__name__ = 'tablib'
|
|
||||||
__version__ = '0.6.1'
|
|
||||||
__build__ = 0x000601
|
|
||||||
__author__ = 'Kenneth Reitz'
|
__author__ = 'Kenneth Reitz'
|
||||||
__license__ = 'MIT'
|
__license__ = 'MIT'
|
||||||
__copyright__ = 'Copyright 2010 Kenneth Reitz'
|
__copyright__ = 'Copyright 2010 Kenneth Reitz'
|
||||||
@@ -32,29 +18,27 @@ class Dataset(object):
|
|||||||
"""Epic Tabular-Dataset object. """
|
"""Epic Tabular-Dataset object. """
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self._data = None
|
|
||||||
self._saved_file = None
|
|
||||||
self._saved_format = None
|
|
||||||
self._data = list(args)
|
self._data = list(args)
|
||||||
self.__headers = None
|
self.__headers = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.headers = kwargs['headers']
|
self.headers = kwargs['headers']
|
||||||
except KeyError, why:
|
except KeyError:
|
||||||
self.headers = None
|
self.headers = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.title = kwargs['title']
|
self.title = kwargs['title']
|
||||||
except KeyError, why:
|
except KeyError:
|
||||||
self.title = None
|
self.title = None
|
||||||
|
|
||||||
|
self._register_formats()
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return self.height
|
return self.height
|
||||||
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
if is_string(key):
|
if isinstance(key, basestring):
|
||||||
if key in self.headers:
|
if key in self.headers:
|
||||||
pos = self.headers.index(key) # get 'key' index from each data
|
pos = self.headers.index(key) # get 'key' index from each data
|
||||||
return [row[pos] for row in self._data]
|
return [row[pos] for row in self._data]
|
||||||
@@ -79,11 +63,30 @@ class Dataset(object):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
return '<dataset object>'
|
return '<dataset object>'
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _register_formats(cls):
|
||||||
|
"""Adds format properties."""
|
||||||
|
for fmt in formats:
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
setattr(cls, fmt.title, property(fmt.export_set, fmt.import_set))
|
||||||
|
except AttributeError:
|
||||||
|
setattr(cls, fmt.title, property(fmt.export_set))
|
||||||
|
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
def _validate(self, row=None, safety=False):
|
|
||||||
|
def _validate(self, row=None, col=None, safety=False):
|
||||||
"""Assures size of every row in dataset is of proper proportions."""
|
"""Assures size of every row in dataset is of proper proportions."""
|
||||||
if row:
|
if row:
|
||||||
is_valid = (len(row) == self.width) if self.width else True
|
is_valid = (len(row) == self.width) if self.width else True
|
||||||
|
elif col:
|
||||||
|
if self.headers:
|
||||||
|
is_valid = (len(col) - 1) == self.height
|
||||||
|
else:
|
||||||
|
is_valid = (len(col) == self.height) if self.height else True
|
||||||
else:
|
else:
|
||||||
is_valid = all((len(x)== self.width for x in self._data))
|
is_valid = all((len(x)== self.width for x in self._data))
|
||||||
|
|
||||||
@@ -108,6 +111,7 @@ class Dataset(object):
|
|||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def height(self):
|
def height(self):
|
||||||
"""Returns the height of the Dataset."""
|
"""Returns the height of the Dataset."""
|
||||||
@@ -119,86 +123,101 @@ class Dataset(object):
|
|||||||
"""Returns the width of the Dataset."""
|
"""Returns the width of the Dataset."""
|
||||||
try:
|
try:
|
||||||
return len(self._data[0])
|
return len(self._data[0])
|
||||||
except IndexError, why:
|
except IndexError:
|
||||||
try:
|
try:
|
||||||
return len(self.headers)
|
return len(self.headers)
|
||||||
except TypeError, e:
|
except TypeError:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def headers(self):
|
def headers(self):
|
||||||
"""Headers property."""
|
"""Headers property."""
|
||||||
return self.__headers
|
return self.__headers
|
||||||
|
|
||||||
|
|
||||||
@headers.setter
|
@headers.setter
|
||||||
def headers(self, collection):
|
def headers(self, collection):
|
||||||
"""Validating headers setter."""
|
"""Validating headers setter."""
|
||||||
self._validate(collection)
|
self._validate(collection)
|
||||||
self.__headers = collection
|
if collection:
|
||||||
|
try:
|
||||||
|
self.__headers = list(collection)
|
||||||
|
except TypeError:
|
||||||
|
raise TypeError
|
||||||
|
else:
|
||||||
|
self.__headers = None
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dict(self):
|
def dict(self):
|
||||||
"""Returns python dict of Dataset."""
|
"""Returns python dict of Dataset."""
|
||||||
return self._package()
|
return self._package()
|
||||||
|
|
||||||
@property
|
|
||||||
def json(self):
|
@dict.setter
|
||||||
"""Returns JSON representation of Dataset."""
|
def dict(self, pickle):
|
||||||
return json.dumps(self.dict)
|
"""Returns python dict of Dataset."""
|
||||||
|
if not len(pickle):
|
||||||
|
return
|
||||||
|
if isinstance(pickle[0], list):
|
||||||
|
for row in pickle:
|
||||||
|
self.append(row)
|
||||||
|
elif isinstance(pickle[0], dict):
|
||||||
|
self.headers = pickle[0].keys()
|
||||||
|
for row in pickle:
|
||||||
|
self.append(row.values())
|
||||||
|
else:
|
||||||
|
raise UnsupportedFormat
|
||||||
|
|
||||||
|
|
||||||
@property
|
def append(self, row=None, col=None):
|
||||||
def yaml(self):
|
|
||||||
"""Returns YAML representation of Dataset."""
|
|
||||||
return yaml.dump(self.dict)
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
|
||||||
def csv(self):
|
|
||||||
"""Returns CSV representation of Dataset."""
|
|
||||||
stream = cStringIO.StringIO()
|
|
||||||
_csv = csv.writer(stream)
|
|
||||||
|
|
||||||
for row in self._package(dicts=False):
|
|
||||||
_csv.writerow(row)
|
|
||||||
|
|
||||||
return stream.getvalue()
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
|
||||||
def xls(self):
|
|
||||||
"""Returns XLS representation of Dataset."""
|
|
||||||
stream = cStringIO.StringIO()
|
|
||||||
|
|
||||||
wb = xlwt.Workbook()
|
|
||||||
ws = wb.add_sheet(self.title if self.title else 'Tabbed Dataset')
|
|
||||||
for i, row in enumerate(self._package(dicts=False)):
|
|
||||||
for j, col in enumerate(row):
|
|
||||||
ws.write(i, j, str(col))
|
|
||||||
|
|
||||||
wb.save(stream)
|
|
||||||
return stream.getvalue()
|
|
||||||
|
|
||||||
|
|
||||||
def append(self, row):
|
|
||||||
"""Adds a row to the end of Dataset"""
|
"""Adds a row to the end of Dataset"""
|
||||||
self._validate(row)
|
if row:
|
||||||
self._data.append(tuple(row))
|
self._validate(row)
|
||||||
|
self._data.append(tuple(row))
|
||||||
|
elif col:
|
||||||
|
self._validate(col=col)
|
||||||
|
|
||||||
|
if self.headers:
|
||||||
|
# pop the first item off, add to headers
|
||||||
|
self.headers.append(col[0])
|
||||||
|
col = col[1:]
|
||||||
|
|
||||||
|
if self.height and self.width:
|
||||||
|
|
||||||
|
for i, row in enumerate(self._data):
|
||||||
|
_row = list(row)
|
||||||
|
_row.append(col[i])
|
||||||
|
self._data[i] = tuple(_row)
|
||||||
|
else:
|
||||||
|
self._data = [tuple([row]) for row in col]
|
||||||
|
|
||||||
|
|
||||||
def index(self, i, row):
|
def insert(self, i, row=None, col=None):
|
||||||
"""Inserts a row at given position in Dataset"""
|
"""Inserts a row at given position in Dataset"""
|
||||||
self._validate(row)
|
if row:
|
||||||
self._data.insert(i, tuple(row))
|
self._validate(row)
|
||||||
|
self._data.insert(i, tuple(row))
|
||||||
|
elif col:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def wipe(self):
|
||||||
|
"""Erases all data from Dataset."""
|
||||||
|
self._data = list()
|
||||||
|
self.__headers = None
|
||||||
|
|
||||||
|
|
||||||
class DataBook(object):
|
class Databook(object):
|
||||||
"""A book of Dataset objects.
|
"""A book of Dataset objects.
|
||||||
Currently, this exists only for XLS workbook support.
|
Currently, this exists only for XLS workbook support.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sets=[]):
|
def __init__(self, sets=[]):
|
||||||
self._datasets = sets
|
self._datasets = sets
|
||||||
|
self._register_formats()
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
try:
|
try:
|
||||||
@@ -206,14 +225,34 @@ class DataBook(object):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
return '<databook object>'
|
return '<databook object>'
|
||||||
|
|
||||||
|
def wipe(self):
|
||||||
|
"""Wipe book clean."""
|
||||||
|
self._datasets = []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _register_formats(cls):
|
||||||
|
"""Adds format properties."""
|
||||||
|
for fmt in formats:
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
setattr(cls, fmt.title, property(fmt.export_book, fmt.import_book))
|
||||||
|
except AttributeError:
|
||||||
|
setattr(cls, fmt.title, property(fmt.export_book))
|
||||||
|
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def add_sheet(self, dataset):
|
def add_sheet(self, dataset):
|
||||||
"""Add given dataset ."""
|
"""Adds given dataset."""
|
||||||
if type(dataset) is Dataset:
|
if type(dataset) is Dataset:
|
||||||
self._datasets.append(dataset)
|
self._datasets.append(dataset)
|
||||||
else:
|
else:
|
||||||
raise InvalidDatasetType
|
raise InvalidDatasetType
|
||||||
|
|
||||||
|
|
||||||
def _package(self):
|
def _package(self):
|
||||||
|
"""Packages Databook for delivery."""
|
||||||
collector = []
|
collector = []
|
||||||
for dset in self._datasets:
|
for dset in self._datasets:
|
||||||
collector.append(dict(
|
collector.append(dict(
|
||||||
@@ -222,48 +261,21 @@ class DataBook(object):
|
|||||||
))
|
))
|
||||||
return collector
|
return collector
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def size(self):
|
def size(self):
|
||||||
"""The number of the Datasets within DataBook."""
|
"""The number of the Datasets within DataBook."""
|
||||||
return len(self._datasets)
|
return len(self._datasets)
|
||||||
|
|
||||||
|
|
||||||
@property
|
|
||||||
def xls(self):
|
|
||||||
"""Returns XLS representation of DataBook."""
|
|
||||||
|
|
||||||
stream = cStringIO.StringIO()
|
|
||||||
wb = xlwt.Workbook()
|
|
||||||
|
|
||||||
for dset in self._datasets:
|
|
||||||
ws = wb.add_sheet(dset.title if dset.title else 'Tabbed Dataset %s' % (int(random.random() * 100000000)))
|
|
||||||
|
|
||||||
#for row in self._package(dicts=False):
|
|
||||||
for i, row in enumerate(dset._package(dicts=False)):
|
|
||||||
for j, col in enumerate(row):
|
|
||||||
ws.write(i, j, str(col))
|
|
||||||
|
|
||||||
wb.save(stream)
|
|
||||||
return stream.getvalue()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def json(self):
|
|
||||||
"""Returns JSON representation of Databook."""
|
|
||||||
|
|
||||||
return json.dumps(self._package())
|
|
||||||
|
|
||||||
@property
|
|
||||||
def yaml(self):
|
|
||||||
"""Returns YAML representation of Databook."""
|
|
||||||
|
|
||||||
return yaml.dump(self._package())
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidDatasetType(Exception):
|
class InvalidDatasetType(Exception):
|
||||||
"Only Datasets can be added to a DataBook"
|
"Only Datasets can be added to a DataBook"
|
||||||
|
|
||||||
|
|
||||||
class InvalidDimensions(Exception):
|
class InvalidDimensions(Exception):
|
||||||
"Invalid size"
|
"Invalid size"
|
||||||
|
|
||||||
|
|
||||||
class UnsupportedFormat(NotImplementedError):
|
class UnsupportedFormat(NotImplementedError):
|
||||||
"Format is not supported"
|
"Format is not supported"
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
""" Tablib - formats
|
||||||
|
"""
|
||||||
|
|
||||||
|
import _csv as csv
|
||||||
|
import _json as json
|
||||||
|
import _xls as xls
|
||||||
|
import _yaml as yaml
|
||||||
|
|
||||||
|
FORMATS = (csv, json, xls, yaml)
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
""" Tablib - CSV Support.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import cStringIO
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
|
||||||
|
import simplejson as json
|
||||||
|
|
||||||
|
import tablib
|
||||||
|
|
||||||
|
|
||||||
|
title = 'csv'
|
||||||
|
extentions = ('csv',)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def export_set(dataset):
|
||||||
|
"""Returns CSV representation of Dataset."""
|
||||||
|
stream = cStringIO.StringIO()
|
||||||
|
_csv = csv.writer(stream)
|
||||||
|
|
||||||
|
for row in dataset._package(dicts=False):
|
||||||
|
_csv.writerow(row)
|
||||||
|
|
||||||
|
return stream.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
def import_set(dset, in_stream, headers=True):
|
||||||
|
"""Returns dataset from CSV stream."""
|
||||||
|
|
||||||
|
dset.wipe()
|
||||||
|
|
||||||
|
rows = csv.reader(in_stream.split())
|
||||||
|
for i, row in enumerate(rows):
|
||||||
|
|
||||||
|
if (i == 0) and (headers):
|
||||||
|
dset.headers = row
|
||||||
|
else:
|
||||||
|
dset.append(row)
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
""" Tablib - JSON Support
|
||||||
|
"""
|
||||||
|
|
||||||
|
import simplejson as json
|
||||||
|
import tablib.core
|
||||||
|
|
||||||
|
title = 'json'
|
||||||
|
extentions = ('json', 'jsn')
|
||||||
|
|
||||||
|
|
||||||
|
def export_set(dataset):
|
||||||
|
"""Returns JSON representation of Dataset."""
|
||||||
|
return json.dumps(dataset.dict)
|
||||||
|
|
||||||
|
|
||||||
|
def export_book(databook):
|
||||||
|
"""Returns JSON representation of Databook."""
|
||||||
|
return json.dumps(databook._package())
|
||||||
|
|
||||||
|
|
||||||
|
def import_set(dset, in_stream):
|
||||||
|
"""Returns dataset from JSON stream."""
|
||||||
|
|
||||||
|
dset.wipe()
|
||||||
|
dset.dict = json.loads(in_stream)
|
||||||
|
|
||||||
|
|
||||||
|
def import_book(dbook, in_stream):
|
||||||
|
"""Returns databook from JSON stream."""
|
||||||
|
|
||||||
|
dbook.wipe()
|
||||||
|
for sheet in json.loads(in_stream):
|
||||||
|
data = tablib.core.Dataset()
|
||||||
|
data.title = sheet['title']
|
||||||
|
data.dict = sheet['data']
|
||||||
|
dbook.add_sheet(data)
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
""" Tablib - XLS Support.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import xlwt
|
||||||
|
import cStringIO
|
||||||
|
|
||||||
|
|
||||||
|
title = 'xls'
|
||||||
|
extentions = ('xls',)
|
||||||
|
|
||||||
|
|
||||||
|
def export_set(dataset):
|
||||||
|
"""Returns XLS representation of Dataset."""
|
||||||
|
|
||||||
|
wb = xlwt.Workbook(encoding='utf8')
|
||||||
|
ws = wb.add_sheet(dataset.title if dataset.title else 'Tabbed Dataset')
|
||||||
|
|
||||||
|
for i, row in enumerate(dataset._package(dicts=False)):
|
||||||
|
for j, col in enumerate(row):
|
||||||
|
ws.write(i, j, col)
|
||||||
|
|
||||||
|
stream = cStringIO.StringIO()
|
||||||
|
wb.save(stream)
|
||||||
|
return stream.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
def export_book(databook):
|
||||||
|
"""Returns XLS representation of DataBook."""
|
||||||
|
|
||||||
|
wb = xlwt.Workbook(encoding='utf8')
|
||||||
|
|
||||||
|
for i, dset in enumerate(databook._datasets):
|
||||||
|
ws = wb.add_sheet(dset.title if dset.title else 'Sheet%s' % (i))
|
||||||
|
|
||||||
|
#for row in self._package(dicts=False):
|
||||||
|
for i, row in enumerate(dset._package(dicts=False)):
|
||||||
|
for j, col in enumerate(row):
|
||||||
|
ws.write(i, j, col)
|
||||||
|
|
||||||
|
|
||||||
|
stream = cStringIO.StringIO()
|
||||||
|
wb.save(stream)
|
||||||
|
return stream.getvalue()
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
""" Tablib - YAML Support.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
import tablib
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
title = 'yaml'
|
||||||
|
extentions = ('yaml', 'yml')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def export_set(dataset):
|
||||||
|
"""Returns YAML representation of Dataset."""
|
||||||
|
return yaml.dump(dataset.dict)
|
||||||
|
|
||||||
|
|
||||||
|
def export_book(databook):
|
||||||
|
"""Returns YAML representation of Databook."""
|
||||||
|
return yaml.dump(databook._package())
|
||||||
|
|
||||||
|
|
||||||
|
def import_set(dset, in_stream):
|
||||||
|
"""Returns dataset from YAML stream."""
|
||||||
|
|
||||||
|
dset.wipe()
|
||||||
|
dset.dict = yaml.load(in_stream)
|
||||||
|
|
||||||
|
|
||||||
|
def import_book(dbook, in_stream):
|
||||||
|
"""Returns databook from YAML stream."""
|
||||||
|
|
||||||
|
dbook.wipe()
|
||||||
|
|
||||||
|
for sheet in yaml.load(in_stream):
|
||||||
|
data = tablib.core.Dataset()
|
||||||
|
data.title = sheet['title']
|
||||||
|
data.dict = sheet['data']
|
||||||
|
dbook.add_sheet(data)
|
||||||
+19
-7
@@ -1,5 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
""" Tablib - General Helpers.
|
||||||
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
@@ -10,16 +13,25 @@ class Struct(object):
|
|||||||
self.__dict__.update(entries)
|
self.__dict__.update(entries)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return getattr(self, key)
|
return getattr(self, key, None)
|
||||||
|
|
||||||
|
def dictionary(self):
|
||||||
|
"""Returns dictionary representation of object."""
|
||||||
|
return self.__dict__
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
"""Returns items within object."""
|
||||||
|
return self.__dict__.items()
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
"""Returns keys within object."""
|
||||||
|
return self.__dict__.keys()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def piped():
|
def piped():
|
||||||
"""Returns piped input via stdin, else False"""
|
"""Returns piped input via stdin, else False."""
|
||||||
with sys.stdin as stdin:
|
with sys.stdin as stdin:
|
||||||
|
# TTY is only way to detect if stdin contains data
|
||||||
return stdin.read() if not stdin.isatty() else None
|
return stdin.read() if not stdin.isatty() else None
|
||||||
|
|
||||||
|
|
||||||
def is_string(obj):
|
|
||||||
"""Tests if an object is a string"""
|
|
||||||
|
|
||||||
return True if type(obj).__name__ == 'str' else False
|
|
||||||
Regular → Executable
+256
-13
@@ -1,40 +1,283 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Tests for tablib."""
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import tablib
|
import tablib
|
||||||
|
|
||||||
|
|
||||||
class TablibTestCase(unittest.TestCase):
|
class TablibTestCase(unittest.TestCase):
|
||||||
|
"""Tablib test cases."""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
pass
|
"""Create simple data set with headers."""
|
||||||
|
|
||||||
|
global data, book
|
||||||
|
data = tablib.Dataset()
|
||||||
|
book = tablib.Databook()
|
||||||
|
|
||||||
|
self.headers = ('first_name', 'last_name', 'gpa')
|
||||||
|
self.john = ('John', 'Adams', 90)
|
||||||
|
self.george = ('George', 'Washington', 67)
|
||||||
|
self.tom = ('Thomas', 'Jefferson', 50)
|
||||||
|
|
||||||
|
self.founders = tablib.Dataset(headers=self.headers)
|
||||||
|
self.founders.append(self.john)
|
||||||
|
self.founders.append(self.george)
|
||||||
|
self.founders.append(self.tom)
|
||||||
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
"""Teardown."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_empty_append(self):
|
def test_empty_append(self):
|
||||||
|
"""Verify append() correctly adds tuple with no headers."""
|
||||||
data = tablib.Dataset()
|
new_row = (1, 2, 3)
|
||||||
|
|
||||||
new_row = (1,2,3)
|
|
||||||
data.append(new_row)
|
data.append(new_row)
|
||||||
|
|
||||||
|
# Verify width/data
|
||||||
self.assertTrue(data.width == len(new_row))
|
self.assertTrue(data.width == len(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
|
||||||
data = tablib.Dataset()
|
headers and data.
|
||||||
|
"""
|
||||||
data.headers = ['first', 'second']
|
data.headers = ['first', 'second']
|
||||||
new_row = (1,2,3,4)
|
new_row = (1, 2, 3, 4)
|
||||||
|
|
||||||
self.assertRaises(tablib.InvalidDimensions, data.append, new_row)
|
self.assertRaises(tablib.InvalidDimensions, data.append, new_row)
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_column(self):
|
||||||
|
"""Verify adding column works with/without headers."""
|
||||||
|
|
||||||
|
data.append(['kenneth'])
|
||||||
|
data.append(['bessie'])
|
||||||
|
|
||||||
|
new_col = ['reitz', 'monke']
|
||||||
|
|
||||||
|
data.append(col=new_col)
|
||||||
|
|
||||||
|
self.assertEquals(data[0], ('kenneth', 'reitz'))
|
||||||
|
self.assertEquals(data.width, 2)
|
||||||
|
|
||||||
|
# With Headers
|
||||||
|
data.headers = ('fname', 'lname')
|
||||||
|
new_col = ['age', 21, 22]
|
||||||
|
data.append(col=new_col)
|
||||||
|
|
||||||
|
self.assertEquals(data[new_col[0]], new_col[1:])
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_column_no_data_no_headers(self):
|
||||||
|
"""Verify adding new column with no headers."""
|
||||||
|
|
||||||
|
new_col = ('reitz', 'monke')
|
||||||
|
|
||||||
|
data.append(col=new_col)
|
||||||
|
|
||||||
|
self.assertEquals(data[0], tuple([new_col[0]]))
|
||||||
|
self.assertEquals(data.width, 1)
|
||||||
|
self.assertEquals(data.height, len(new_col))
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_column_no_data_with_headers(self):
|
||||||
|
"""Verify adding new column with headers."""
|
||||||
|
|
||||||
|
data.headers = ('first', 'last')
|
||||||
|
|
||||||
|
new_col = ('age',)
|
||||||
|
data.append(col=new_col)
|
||||||
|
|
||||||
|
self.assertEquals(len(data.headers), 3)
|
||||||
|
self.assertEquals(data.width, 3)
|
||||||
|
|
||||||
|
new_col = ('foo', 'bar')
|
||||||
|
|
||||||
|
self.assertRaises(tablib.InvalidDimensions, data.append, col=new_col)
|
||||||
|
|
||||||
|
|
||||||
|
def test_header_slicing(self):
|
||||||
|
"""Verify slicing by headers."""
|
||||||
|
|
||||||
|
self.assertEqual(self.founders['first_name'],
|
||||||
|
[self.john[0], self.george[0], self.tom[0]])
|
||||||
|
self.assertEqual(self.founders['last_name'],
|
||||||
|
[self.john[1], self.george[1], self.tom[1]])
|
||||||
|
self.assertEqual(self.founders['gpa'],
|
||||||
|
[self.john[2], self.george[2], self.tom[2]])
|
||||||
|
|
||||||
|
|
||||||
|
def test_data_slicing(self):
|
||||||
|
"""Verify slicing by data."""
|
||||||
|
|
||||||
|
# Slice individual rows
|
||||||
|
self.assertEqual(self.founders[0], self.john)
|
||||||
|
self.assertEqual(self.founders[:1], [self.john])
|
||||||
|
self.assertEqual(self.founders[1:2], [self.george])
|
||||||
|
self.assertEqual(self.founders[-1], self.tom)
|
||||||
|
self.assertEqual(self.founders[3:], [])
|
||||||
|
|
||||||
|
# Slice multiple rows
|
||||||
|
self.assertEqual(self.founders[:], [self.john, self.george, self.tom])
|
||||||
|
self.assertEqual(self.founders[0:2], [self.john, self.george])
|
||||||
|
self.assertEqual(self.founders[1:3], [self.george, self.tom])
|
||||||
|
self.assertEqual(self.founders[2:], [self.tom])
|
||||||
|
|
||||||
|
|
||||||
|
def test_delete(self):
|
||||||
|
"""Verify deleting from dataset works."""
|
||||||
|
|
||||||
|
# Delete from front of object
|
||||||
|
del self.founders[0]
|
||||||
|
self.assertEqual(self.founders[:], [self.george, self.tom])
|
||||||
|
|
||||||
|
# Verify dimensions, width should NOT change
|
||||||
|
self.assertEqual(self.founders.height, 2)
|
||||||
|
self.assertEqual(self.founders.width, 3)
|
||||||
|
|
||||||
|
# Delete from back of object
|
||||||
|
del self.founders[1]
|
||||||
|
self.assertEqual(self.founders[:], [self.george])
|
||||||
|
|
||||||
|
# Verify dimensions, width should NOT change
|
||||||
|
self.assertEqual(self.founders.height, 1)
|
||||||
|
self.assertEqual(self.founders.width, 3)
|
||||||
|
|
||||||
|
# Delete from invalid index
|
||||||
|
self.assertRaises(IndexError, self.founders.__delitem__, 3)
|
||||||
|
|
||||||
|
|
||||||
|
def test_csv_export(self):
|
||||||
|
"""Verify exporting dataset object as CSV."""
|
||||||
|
|
||||||
|
# Build up the csv string with headers first, followed by each row
|
||||||
|
csv = ''
|
||||||
|
for col in self.headers:
|
||||||
|
csv += col + ','
|
||||||
|
|
||||||
|
csv = csv.strip(',') + '\r\n'
|
||||||
|
|
||||||
|
for founder in self.founders:
|
||||||
|
for col in founder:
|
||||||
|
csv += str(col) + ','
|
||||||
|
csv = csv.strip(',') + '\r\n'
|
||||||
|
|
||||||
|
self.assertEqual(csv, self.founders.csv)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unicode_append(self):
|
||||||
|
"""Passes in a single unicode charecter and exports."""
|
||||||
|
|
||||||
|
new_row = ('å', 'é')
|
||||||
|
data.append(new_row)
|
||||||
|
|
||||||
|
data.json
|
||||||
|
data.yaml
|
||||||
|
data.csv
|
||||||
|
data.xls
|
||||||
|
|
||||||
|
|
||||||
|
def test_book_export_no_exceptions(self):
|
||||||
|
"""Test that varoius exports don't error out."""
|
||||||
|
|
||||||
|
book = tablib.Databook()
|
||||||
|
book.add_sheet(data)
|
||||||
|
|
||||||
|
book.json
|
||||||
|
book.yaml
|
||||||
|
book.xls
|
||||||
|
|
||||||
|
|
||||||
|
def test_json_import_set(self):
|
||||||
|
"""Generate and import JSON set serialization."""
|
||||||
|
data.append(self.john)
|
||||||
|
data.append(self.george)
|
||||||
|
data.headers = self.headers
|
||||||
|
|
||||||
|
_json = data.json
|
||||||
|
|
||||||
|
data.json = _json
|
||||||
|
|
||||||
|
self.assertEqual(_json, data.json)
|
||||||
|
|
||||||
|
|
||||||
|
def test_json_import_book(self):
|
||||||
|
"""Generate and import JSON book serialization."""
|
||||||
|
data.append(self.john)
|
||||||
|
data.append(self.george)
|
||||||
|
data.headers = self.headers
|
||||||
|
|
||||||
|
book.add_sheet(data)
|
||||||
|
_json = book.json
|
||||||
|
|
||||||
|
book.json = _json
|
||||||
|
|
||||||
|
self.assertEqual(_json, book.json)
|
||||||
|
|
||||||
|
|
||||||
|
def test_yaml_import_set(self):
|
||||||
|
"""Generate and import YAML set serialization."""
|
||||||
|
data.append(self.john)
|
||||||
|
data.append(self.george)
|
||||||
|
data.headers = self.headers
|
||||||
|
|
||||||
|
_yaml = data.yaml
|
||||||
|
|
||||||
|
data.yaml = _yaml
|
||||||
|
|
||||||
|
self.assertEqual(_yaml, data.yaml)
|
||||||
|
|
||||||
|
|
||||||
# def test_adding_header with (self):
|
def test_yaml_import_book(self):
|
||||||
|
"""Generate and import YAML book serialization."""
|
||||||
|
data.append(self.john)
|
||||||
|
data.append(self.george)
|
||||||
|
data.headers = self.headers
|
||||||
|
|
||||||
|
book.add_sheet(data)
|
||||||
|
_yaml = book.yaml
|
||||||
|
|
||||||
|
book.yaml = _yaml
|
||||||
|
|
||||||
|
self.assertEqual(_yaml, book.yaml)
|
||||||
|
|
||||||
|
|
||||||
|
def test_csv_import_set(self):
|
||||||
|
"""Generate and import CSV set serialization."""
|
||||||
|
data.append(self.john)
|
||||||
|
data.append(self.george)
|
||||||
|
data.headers = self.headers
|
||||||
|
|
||||||
|
_csv = data.csv
|
||||||
|
|
||||||
|
data.csv = _csv
|
||||||
|
|
||||||
|
self.assertEqual(_csv, data.csv)
|
||||||
|
|
||||||
|
|
||||||
|
def test_wipe(self):
|
||||||
|
"""Purge a dataset."""
|
||||||
|
|
||||||
|
new_row = (1, 2, 3)
|
||||||
|
data.append(new_row)
|
||||||
|
|
||||||
|
# Verify width/data
|
||||||
|
self.assertTrue(data.width == len(new_row))
|
||||||
|
self.assertTrue(data[0] == new_row)
|
||||||
|
|
||||||
|
data.wipe()
|
||||||
|
new_row = (1, 2, 3, 4)
|
||||||
|
data.append(new_row)
|
||||||
|
self.assertTrue(data.width == len(new_row))
|
||||||
|
self.assertTrue(data[0] == new_row)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user