summaryrefslogtreecommitdiff
path: root/tablib
diff options
context:
space:
mode:
Diffstat (limited to 'tablib')
-rw-r--r--tablib/formats/_csv.py21
-rw-r--r--tablib/packages/unicodecsv/__init__.py105
2 files changed, 123 insertions, 3 deletions
diff --git a/tablib/formats/_csv.py b/tablib/formats/_csv.py
index 4b1dc02..bfe8b0f 100644
--- a/tablib/formats/_csv.py
+++ b/tablib/formats/_csv.py
@@ -5,12 +5,17 @@
import sys
if sys.version_info[0] > 2:
+ is_py3 = True
+
from io import StringIO
+ import csv
else:
+ is_py3 = False
from cStringIO import StringIO
+ import tablib.packages.unicodecsv as csv
+
-import csv
import os
import tablib
@@ -20,11 +25,18 @@ title = 'csv'
extentions = ('csv',)
+DEFAULT_ENCODING = 'utf-8'
+
+
def export_set(dataset):
"""Returns CSV representation of Dataset."""
stream = StringIO()
- _csv = csv.writer(stream)
+
+ if is_py3:
+ _csv = csv.writer(stream)
+ else:
+ _csv = csv.writer(stream, encoding=DEFAULT_ENCODING)
for row in dataset._package(dicts=False):
_csv.writerow(row)
@@ -37,7 +49,10 @@ def import_set(dset, in_stream, headers=True):
dset.wipe()
- rows = csv.reader(in_stream.splitlines())
+ if is_py3:
+ rows = csv.reader(in_stream.splitlines())
+ else:
+ rows = csv.reader(in_stream.splitlines(), encoding=DEFAULT_ENCODING)
for i, row in enumerate(rows):
if (i == 0) and (headers):
diff --git a/tablib/packages/unicodecsv/__init__.py b/tablib/packages/unicodecsv/__init__.py
new file mode 100644
index 0000000..e640987
--- /dev/null
+++ b/tablib/packages/unicodecsv/__init__.py
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+import csv
+from csv import *
+
+#http://semver.org/
+VERSION = (0, 8, 0)
+__version__ = ".".join(map(str,VERSION))
+
+def _stringify(s, encoding):
+ if type(s)==unicode:
+ return s.encode(encoding)
+ elif isinstance(s, (int , float)):
+ pass #let csv.QUOTE_NONNUMERIC do its thing.
+ elif type(s) != str:
+ s=str(s)
+ return s
+
+def _stringify_list(l, encoding):
+ return [_stringify(s, encoding) for s in l]
+
+class UnicodeWriter(object):
+ """
+ >>> import unicodecsv
+ >>> from cStringIO import StringIO
+ >>> f = StringIO()
+ >>> w = unicodecsv.writer(f, encoding='utf-8')
+ >>> w.writerow((u'é', u'ñ'))
+ >>> f.seek(0)
+ >>> r = unicodecsv.reader(f, encoding='utf-8')
+ >>> row = r.next()
+ >>> print row[0], row[1]
+ é ñ
+ """
+ def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
+ self.writer = csv.writer(f)
+ self.dialect = dialect
+ self.encoding = encoding
+ self.writer = csv.writer(f, dialect=dialect, **kwds)
+
+ def writerow(self, row):
+ self.writer.writerow(_stringify_list(row, self.encoding))
+
+ def writerows(self, rows):
+ for row in rows:
+ self.writerow(row)
+writer = UnicodeWriter
+
+class UnicodeReader(object):
+ def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
+ self.reader = csv.reader(f, dialect=dialect, **kwds)
+ self.encoding = encoding
+
+ def next(self):
+ row = self.reader.next()
+ return [unicode(s, self.encoding) for s in row]
+
+ def __iter__(self):
+ return self
+reader = UnicodeReader
+
+class DictWriter(csv.DictWriter):
+ """
+ >>> from cStringIO import StringIO
+ >>> f = StringIO()
+ >>> w = DictWriter(f, ['a', 'b'], restval=u'î')
+ >>> w.writerow({'a':'1'})
+ >>> w.writerow({'a':'1', 'b':u'ø'})
+ >>> w.writerow({'a':u'é'})
+ >>> f.seek(0)
+ >>> r = DictReader(f, fieldnames=['a'], restkey='r')
+ >>> r.next() == {'a':u'1', 'r':[u"î"]}
+ True
+ >>> r.next() == {'a':u'1', 'r':[u"ø"]}
+ True
+ >>> r.next() == {'a':u'é', 'r':[u"î"]}
+ """
+ def __init__(self, csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel', encoding='utf-8', *args, **kwds):
+ self.fieldnames = fieldnames
+ self.encoding = encoding
+ self.restval = restval
+ self.writer = csv.DictWriter(csvfile, fieldnames, restval, extrasaction, dialect, *args, **kwds)
+ def writerow(self, d):
+ for fieldname in self.fieldnames:
+ if fieldname in d:
+ d[fieldname] = _stringify(d[fieldname], self.encoding)
+ else:
+ d[fieldname] = _stringify(self.restval, self.encoding)
+ self.writer.writerow(d)
+
+class DictReader(csv.DictReader):
+ def __init__(self, csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', encoding='utf-8', *args, **kwds):
+ self.restkey = restkey
+ self.encoding = encoding
+ self.reader = csv.DictReader(csvfile, fieldnames, restkey, restval, dialect, *args, **kwds)
+ def next(self):
+ d = self.reader.next()
+ for k, v in d.items():
+ if k == self.restkey:
+ rest = v
+ if rest:
+ d[self.restkey] = [unicode(v, self.encoding) for v in rest]
+ else:
+ if v is not None:
+ d[k] = unicode(v, self.encoding)
+ return d