Compare commits

...

35 Commits

Author SHA1 Message Date
Kenneth Reitz 7f17ccf445 Merge branch 'hotfix/dict' into develop 2010-09-20 14:37:36 -04:00
Kenneth Reitz 9b3268f0ad Whoops. 2010-09-20 14:37:10 -04:00
Kenneth Reitz f386ef8ac8 Merge branch 'feature/unicode' into develop 2010-09-20 14:18:55 -04:00
Kenneth Reitz e8f5e023c4 Version bump (v0.7.0). 2010-09-20 14:18:31 -04:00
Kenneth Reitz 81445aeec8 Updated readme to reflect property to method changes. 2010-09-20 14:05:15 -04:00
Kenneth Reitz f94a236122 Changed export properties to methods. 2010-09-20 14:04:02 -04:00
Kenneth Reitz bfbb7c626f Moved from cStringIO to StringIO. More stable. 2010-09-20 12:50:10 -04:00
Kenneth Reitz be0f77f9ee Merge branch 'release/0.6.4' into develop 2010-09-20 09:21:51 -04:00
Kenneth Reitz 3b44349090 Version bump (0.6.4). 2010-09-20 09:21:02 -04:00
Kenneth Reitz 04a16afa58 Chmox. 2010-09-20 09:14:20 -04:00
Kenneth Reitz a8632125dc Merge branch 'master' into dev 2010-09-20 09:07:31 -04:00
Kenneth Reitz ccf2ebcde2 Version bump (v0.6.4) 2010-09-20 08:57:49 -04:00
Kenneth Reitz 2c60ce9233 String decoding to avoid unicode collisions for XLS output. 2010-09-19 23:51:48 -04:00
Kenneth Reitz 649c7e8bb7 Removed unneeded tuple_check. 2010-09-19 23:31:05 -04:00
Kenneth Reitz 2d3dc5ef71 PEP257. 2010-09-19 23:26:37 -04:00
Kenneth Reitz efc516f366 PEP8. 2010-09-19 23:23:03 -04:00
Kenneth Reitz b2a51fd941 Merge branch 'durden' into develop 2010-09-19 23:13:29 -04:00
Luke Lee d54d70bc22 Added test for csv export 2010-09-19 17:04:14 -05:00
Luke Lee 391ad61bef Improved del test
- Added testing for data set width/height
2010-09-19 16:41:23 -05:00
Luke Lee 99a45814d1 Added tests del functionality 2010-09-19 16:36:17 -05:00
Luke Lee fad3546614 Added docstrings 2010-09-19 16:25:18 -05:00
Luke Lee 7ba2849829 Misc. PEP8 whitespace celeanup 2010-09-19 16:16:31 -05:00
Luke Lee 7ec0f2ef07 Attempt at merging upstream develop branch
- Kept the slicing tests in tact by leaving their setup info. in the main setup
- Moved around some of the test methods to organize them a bit by functionality
2010-09-19 16:14:27 -05:00
Luke Lee bd470684a4 Ignore file update
- Update ignoring of python leftovers
- Added vi noise
2010-09-19 16:06:47 -05:00
Kenneth Reitz dbcea81c17 Inline docs. 2010-09-16 00:59:58 -04:00
Kenneth Reitz 49dc4a249e Removed useless is_string function. 2010-09-15 23:46:56 -04:00
Kenneth Reitz 7cd82f956f Version Bump. 2010-09-15 23:46:40 -04:00
Kenneth Reitz 13c3e537fd reamde update 2010-09-14 00:09:04 -04:00
Luke Lee 52db1ddc3e Fixed typo in test from previous commit 2010-09-13 21:27:35 -05:00
Luke Lee 4755020dd7 Added extra row to base data set
- Testing with 3 rows is a bit more interesting
2010-09-13 21:26:15 -05:00
Luke Lee 5468dd7e67 Added test for slicing data elements 2010-09-13 21:23:20 -05:00
Luke Lee 8673710ddb Refactored creation of data set into setUp
- Broke out tuples for more robust comparisions
2010-09-13 21:08:31 -05:00
Luke Lee f01cf184d4 Added simple test for slicing by headers 2010-09-13 21:03:29 -05:00
Luke Lee 1482ca4a19 Adding docstrings 2010-09-13 20:32:36 -05:00
Luke Lee 93c6c39581 Misc. pep8 cleanups including spaces after ',' and blank line organization 2010-09-13 20:23:31 -05:00
7 changed files with 180 additions and 58 deletions
+4 -2
View File
@@ -4,8 +4,8 @@ dist/*
MANIFEST
# python skin
.pyc
.pyo
*.pyc
*.pyo
# osx noise
.DS_Store
@@ -15,3 +15,5 @@ profile
.idea
.idea/*
# vi noise
*.swp
+21
View File
@@ -1,6 +1,27 @@
History
=======
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)
------------------
* Fixed Dataset.append() error on empty dataset.
+5 -5
View File
@@ -70,7 +70,7 @@ JSON!
+++++
::
>>> print data.json
>>> print data.json()
[
{
"last_name": "Adams",
@@ -89,7 +89,7 @@ YAML!
+++++
::
>>> print data.yaml
>>> print data.yaml()
- {age: 90, first_name: John, last_name: Adams}
- {age: 83, first_name: Henry, last_name: Ford}
@@ -97,7 +97,7 @@ CSV...
++++++
::
>>> print data.csv
>>> print data.csv()
first_name,last_name,age
John,Adams,90
Henry,Ford,83
@@ -106,8 +106,8 @@ EXCEL!
++++++
::
>>> open('people.xls').write(data.xls)
>>> data.xls('people.xls')
It's that easy.
+1 -1
View File
@@ -18,7 +18,7 @@ if sys.argv[-1] == "publish":
setup(
name='tablib',
version='0.6.3',
version='0.7.0',
description='Format agnostic tabular data library (XLS, JSON, YAML, CSV)',
long_description=open('README.rst').read() + '\n\n' +
open('HISTORY.rst').read(),
+31 -27
View File
@@ -8,7 +8,7 @@
import csv
import cStringIO
import StringIO
import random
import simplejson as json
@@ -21,8 +21,8 @@ from helpers import *
# __all__ = ['Dataset', 'DataBook']
__name__ = 'tablib'
__version__ = '0.6.3'
__build__ = 0x000603
__version__ = '0.7.0'
__build__ = 0x000700
__author__ = 'Kenneth Reitz'
__license__ = 'MIT'
__copyright__ = 'Copyright 2010 Kenneth Reitz'
@@ -54,7 +54,7 @@ class Dataset(object):
def __getitem__(self, key):
if is_string(key):
if isinstance(key, basestring):
if key in self.headers:
pos = self.headers.index(key) # get 'key' index from each data
return [row[pos] for row in self._data]
@@ -149,29 +149,25 @@ class Dataset(object):
self.__headers = None
@property
def dict(self):
"""Returns python dict of Dataset."""
return self._package()
@property
def json(self):
"""Returns JSON representation of Dataset."""
return json.dumps(self.dict)
@property
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()
stream = StringIO.StringIO()
_csv = csv.writer(stream)
for row in self._package(dicts=False):
@@ -180,19 +176,23 @@ class Dataset(object):
return stream.getvalue()
@property
def xls(self):
def xls(self, path=None):
"""Returns XLS representation of Dataset."""
stream = cStringIO.StringIO()
wb = xlwt.Workbook()
wb = xlwt.Workbook(encoding='utf8')
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))
ws.write(i, j, col)
wb.save(stream)
return stream.getvalue()
if path:
wb.save(path)
return True
else:
stream = StringIO.StringIO()
wb.save(stream)
return stream.getvalue()
def append(self, row=None, col=None):
@@ -227,7 +227,7 @@ class Dataset(object):
pass
class DataBook(object):
class Databook(object):
"""A book of Dataset objects.
Currently, this exists only for XLS workbook support.
"""
@@ -267,12 +267,11 @@ class DataBook(object):
return len(self._datasets)
@property
def xls(self):
def xls(self, path=None):
"""Returns XLS representation of DataBook."""
stream = cStringIO.StringIO()
wb = xlwt.Workbook()
wb = xlwt.Workbook(encoding='utf8')
for i, dset in enumerate(self._datasets):
ws = wb.add_sheet(dset.title if dset.title else 'Sheet%s' % (i))
@@ -280,20 +279,25 @@ class DataBook(object):
#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))
ws.write(i, j, col)
if path:
wb.save(path)
return True
else:
stream = cStringIO.StringIO()
wb.save(stream)
return stream.getvalue()
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."""
+2 -6
View File
@@ -14,12 +14,8 @@ class Struct(object):
def piped():
"""Returns piped input via stdin, else False"""
"""Returns piped input via stdin, else False."""
with sys.stdin as stdin:
# TTY is only way to detect if stdin contains data
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
+116 -17
View File
@@ -1,36 +1,59 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Tests for tablib."""
import unittest
import tablib
class TablibTestCase(unittest.TestCase):
"""Tablib test cases."""
def setUp(self):
"""Create simple data set with headers."""
global data
data = tablib.Dataset()
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):
"""Teardown."""
pass
def test_empty_append(self):
new_row = (1,2,3)
"""Verify append() correctly adds tuple with no headers."""
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)
def test_empty_append_with_headers(self):
"""Verify append() correctly detects mismatch of number of
headers and data.
"""
data.headers = ['first', 'second']
new_row = (1,2,3,4)
new_row = (1, 2, 3, 4)
self.assertRaises(tablib.InvalidDimensions, data.append, new_row)
def test_add_column(self):
# No Headers
"""Verify adding column works with/without headers."""
data.append(['kenneth'])
data.append(['bessie'])
@@ -48,12 +71,10 @@ class TablibTestCase(unittest.TestCase):
data.append(col=new_col)
self.assertEquals(data[new_col[0]], new_col[1:])
def test_add_column_no_data_no_headers(self):
# no headers
"""Verify adding new column with no headers."""
new_col = ('reitz', 'monke')
@@ -65,8 +86,7 @@ class TablibTestCase(unittest.TestCase):
def test_add_column_no_data_with_headers(self):
# no headers
"""Verify adding new column with headers."""
data.headers = ('first', 'last')
@@ -77,11 +97,90 @@ class TablibTestCase(unittest.TestCase):
self.assertEquals(data.width, 3)
new_col = ('foo', 'bar')
self.assertRaises(tablib.InvalidDimensions, data.append, col=new_col)
def tuple_check(self):
data.append(col=(1,2,3))
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()
if __name__ == '__main__':
unittest.main()
unittest.main()