diff --git a/tablib/core.py b/tablib/core.py
index 69a684b..8ef6312 100644
--- a/tablib/core.py
+++ b/tablib/core.py
@@ -13,6 +13,7 @@ from copy import copy
from operator import itemgetter
from tablib import formats
+import collections
try:
from collections import OrderedDict
@@ -63,7 +64,7 @@ class Row(object):
return {slot: [getattr(self, slot) for slot in self.__slots__]}
def __setstate__(self, state):
- for (k, v) in state.items(): setattr(self, k, v)
+ for (k, v) in list(state.items()): setattr(self, k, v)
def append(self, value):
self._row.append(value)
@@ -89,7 +90,7 @@ class Row(object):
if tag == None:
return False
- elif isinstance(tag, basestring):
+ elif isinstance(tag, str):
return (tag in self.tags)
else:
return bool(len(set(tag) & set(self.tags)))
@@ -159,7 +160,7 @@ class Dataset(object):
def __getitem__(self, key):
- if isinstance(key, basestring):
+ if isinstance(key, str):
if key in self.headers:
pos = self.headers.index(key) # get 'key' index from each data
return [row[pos] for row in self._data]
@@ -179,7 +180,7 @@ class Dataset(object):
def __delitem__(self, key):
- if isinstance(key, basestring):
+ if isinstance(key, str):
if key in self.headers:
@@ -258,7 +259,7 @@ class Dataset(object):
if self.headers:
if dicts:
- data = [OrderedDict(zip(self.headers, data_row)) for data_row in _data]
+ data = [OrderedDict(list(zip(self.headers, data_row))) for data_row in _data]
else:
data = [list(self.headers)] + list(_data)
else:
@@ -277,8 +278,8 @@ class Dataset(object):
else:
header = []
- if len(col) == 1 and callable(col[0]):
- col = map(col[0], self._data)
+ if len(col) == 1 and isinstance(col[0], collections.Callable):
+ col = list(map(col[0], self._data))
col = tuple(header + col)
return col
@@ -367,9 +368,9 @@ class Dataset(object):
# if list of objects
elif isinstance(pickle[0], dict):
self.wipe()
- self.headers = pickle[0].keys()
+ self.headers = list(pickle[0].keys())
for row in pickle:
- self.append(Row(row.values()))
+ self.append(Row(list(row.values())))
else:
raise UnsupportedFormat
@@ -499,7 +500,7 @@ class Dataset(object):
against each cell value.
"""
- if isinstance(col, basestring):
+ if isinstance(col, str):
if col in self.headers:
col = self.headers.index(col) # get 'key' index from each data
else:
@@ -548,8 +549,8 @@ class Dataset(object):
col = list(col)
# Callable Columns...
- if len(col) == 1 and callable(col[0]):
- col = map(col[0], self._data)
+ if len(col) == 1 and isinstance(col[0], collections.Callable):
+ col = list(map(col[0], self._data))
col = self._clean_col(col)
self._validate(col=col)
@@ -587,7 +588,7 @@ class Dataset(object):
Returns a new :class:`Dataset` instance where columns have been
sorted."""
- if isinstance(col, basestring):
+ if isinstance(col, str):
if not self.headers:
raise HeadersNeeded
@@ -794,7 +795,7 @@ def import_set(stream):
format.import_set(data, stream)
return data
- except AttributeError, e:
+ except AttributeError as e:
return None
diff --git a/tablib/formats/__init__.py b/tablib/formats/__init__.py
index 147df31..305026d 100644
--- a/tablib/formats/__init__.py
+++ b/tablib/formats/__init__.py
@@ -3,11 +3,11 @@
""" Tablib - formats
"""
-import _csv as csv
-import _json as json
-import _xls as xls
-import _yaml as yaml
-import _tsv as tsv
-import _html as html
+from . import _csv as csv
+from . import _json as json
+from . import _xls as xls
+from . import _yaml as yaml
+from . import _tsv as tsv
+from . import _html as html
available = (json, xls, yaml, csv, tsv, html)
diff --git a/tablib/formats/_csv.py b/tablib/formats/_csv.py
index b71755b..8174501 100644
--- a/tablib/formats/_csv.py
+++ b/tablib/formats/_csv.py
@@ -3,7 +3,7 @@
""" Tablib - CSV Support.
"""
-import cStringIO
+import io
import csv
import os
@@ -17,7 +17,7 @@ extentions = ('csv',)
def export_set(dataset):
"""Returns CSV representation of Dataset."""
- stream = cStringIO.StringIO()
+ stream = io.StringIO()
_csv = csv.writer(stream)
for row in dataset._package(dicts=False):
diff --git a/tablib/formats/_html.py b/tablib/formats/_html.py
index 13dc055..d3a7459 100644
--- a/tablib/formats/_html.py
+++ b/tablib/formats/_html.py
@@ -3,7 +3,7 @@
""" Tablib - HTML export support.
"""
-from StringIO import StringIO
+from io import StringIO
from tablib.packages import markup
import tablib
diff --git a/tablib/formats/_tsv.py b/tablib/formats/_tsv.py
index 76a5f07..708c4b9 100644
--- a/tablib/formats/_tsv.py
+++ b/tablib/formats/_tsv.py
@@ -3,7 +3,7 @@
""" Tablib - TSV (Tab Separated Values) Support.
"""
-import cStringIO
+import io
import csv
import os
@@ -17,7 +17,7 @@ extentions = ('tsv',)
def export_set(dataset):
"""Returns a TSV representation of Dataset."""
- stream = cStringIO.StringIO()
+ stream = io.StringIO()
_tsv = csv.writer(stream, delimiter='\t')
for row in dataset._package(dicts=False):
diff --git a/tablib/formats/_xls.py b/tablib/formats/_xls.py
index 717a6d5..7c3cb06 100644
--- a/tablib/formats/_xls.py
+++ b/tablib/formats/_xls.py
@@ -3,7 +3,7 @@
""" Tablib - XLS Support.
"""
-import cStringIO
+import io
try:
import xlwt
@@ -27,8 +27,8 @@ def export_set(dataset):
dset_sheet(dataset, ws)
- stream = cStringIO.StringIO()
- wb.save(stream)
+ stream = io.StringIO()
+ wb.save(str(stream))
return stream.getvalue()
@@ -43,7 +43,7 @@ def export_book(databook):
dset_sheet(dset, ws)
- stream = cStringIO.StringIO()
+ stream = io.StringIO()
wb.save(stream)
return stream.getvalue()
diff --git a/tablib/packages/anyjson.py b/tablib/packages/anyjson.py
index 6603751..a7d1a5f 100644
--- a/tablib/packages/anyjson.py
+++ b/tablib/packages/anyjson.py
@@ -53,7 +53,7 @@ class _JsonImplementation(object):
"""Incapsulates a JSON implementation"""
def __init__(self, modspec):
- modinfo = dict(zip(_fields, modspec))
+ modinfo = dict(list(zip(_fields, modspec)))
# No try block. We want importerror to end up at caller
module = self._attempt_load(modinfo["modname"])
@@ -64,9 +64,9 @@ class _JsonImplementation(object):
self._encode_error = modinfo["encerror"]
self._decode_error = modinfo["decerror"]
- if isinstance(modinfo["encerror"], basestring):
+ if isinstance(modinfo["encerror"], str):
self._encode_error = getattr(module, modinfo["encerror"])
- if isinstance(modinfo["decerror"], basestring):
+ if isinstance(modinfo["decerror"], str):
self._decode_error = getattr(module, modinfo["decerror"])
self.name = modinfo["modname"]
@@ -82,7 +82,7 @@ class _JsonImplementation(object):
TypeError if the object could not be serialized."""
try:
return self._encode(data)
- except self._encode_error, exc:
+ except self._encode_error as exc:
raise TypeError(*exc.args)
def deserialize(self, s):
@@ -90,7 +90,7 @@ class _JsonImplementation(object):
ValueError if the string vould not be parsed."""
try:
return self._decode(s)
- except self._decode_error, exc:
+ except self._decode_error as exc:
raise ValueError(*exc.args)
diff --git a/tablib/packages/markup.py b/tablib/packages/markup.py
index 234f116..0e1c6a1 100644
--- a/tablib/packages/markup.py
+++ b/tablib/packages/markup.py
@@ -68,7 +68,7 @@ class element:
"""Append the actual tags to content."""
out = "<%s" % tag
- for key, value in kwargs.iteritems( ):
+ for key, value in kwargs.items( ):
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.
if key == 'http_equiv': # special cases, maybe change _ to - overall?
@@ -156,17 +156,17 @@ class page:
if mode == 'strict_html' or mode == 'html':
self.onetags = valid_onetags
- self.onetags += map( string.lower, self.onetags )
+ self.onetags += list(map( string.lower, self.onetags ))
self.twotags = valid_twotags
- self.twotags += map( string.lower, self.twotags )
+ self.twotags += list(map( string.lower, self.twotags ))
self.deptags = deprecated_onetags + deprecated_twotags
- self.deptags += map( string.lower, self.deptags )
+ self.deptags += list(map( string.lower, self.deptags ))
self.mode = 'strict_html'
elif mode == 'loose_html':
self.onetags = valid_onetags + deprecated_onetags
- self.onetags += map( string.lower, self.onetags )
+ self.onetags += list(map( string.lower, self.onetags ))
self.twotags = valid_twotags + deprecated_twotags
- self.twotags += map( string.lower, self.twotags )
+ self.twotags += list(map( string.lower, self.twotags ))
self.mode = mode
elif mode == 'xml':
if onetags and twotags:
@@ -183,7 +183,7 @@ class page:
def __getattr__( self, attr ):
if attr.startswith("__") and attr.endswith("__"):
- raise AttributeError, attr
+ raise AttributeError(attr)
return element( attr, case=self.case, parent=self )
def __str__( self ):
@@ -307,7 +307,7 @@ class page:
"""This convenience function is only useful for html.
It adds css stylesheet(s) to the document via the element."""
- if isinstance( filelist, basestring ):
+ if isinstance( filelist, str ):
self.link( href=filelist, rel='stylesheet', type='text/css', media='all' )
else:
for file in filelist:
@@ -319,20 +319,20 @@ class page:
a dictionary of the form { 'name':'content' }."""
if isinstance( mydict, dict ):
- for name, content in mydict.iteritems( ):
+ for name, content in mydict.items( ):
self.meta( name=name, content=content )
else:
- raise TypeError, "Metainfo should be called with a dictionary argument of name:content pairs."
+ raise TypeError("Metainfo should be called with a dictionary argument of name:content pairs.")
def scripts( self, mydict ):
"""Only useful in html, mydict is dictionary of src:type pairs will
be rendered as """
if isinstance( mydict, dict ):
- for src, type in mydict.iteritems( ):
+ for src, type in mydict.items( ):
self.script( '', src=src, type='text/%s' % type )
else:
- raise TypeError, "Script should be given a dictionary of src:type pairs."
+ raise TypeError("Script should be given a dictionary of src:type pairs.")
class _oneliner:
@@ -345,7 +345,7 @@ class _oneliner:
def __getattr__( self, attr ):
if attr.startswith("__") and attr.endswith("__"):
- raise AttributeError, attr
+ raise AttributeError(attr)
return element( attr, case=self.case, parent=None )
oneliner = _oneliner( case='lower' )
@@ -359,14 +359,14 @@ def _argsdicts( args, mydict ):
elif len( args ) == 1:
args = _totuple( args[0] )
else:
- raise Exception, "We should have never gotten here."
+ raise Exception("We should have never gotten here.")
- mykeys = mydict.keys( )
- myvalues = map( _totuple, mydict.values( ) )
+ mykeys = list(mydict.keys( ))
+ myvalues = list(map( _totuple, list(mydict.values( )) ))
- maxlength = max( map( len, [ args ] + myvalues ) )
+ maxlength = max( list(map( len, [ args ] + myvalues )) )
- for i in xrange( maxlength ):
+ for i in range( maxlength ):
thisdict = { }
for key, value in zip( mykeys, myvalues ):
try:
@@ -383,7 +383,7 @@ def _argsdicts( args, mydict ):
def _totuple( x ):
"""Utility stuff to convert string, int, float, None or anything to a usable tuple."""
- if isinstance( x, basestring ):
+ if isinstance( x, str ):
out = x,
elif isinstance( x, ( int, float ) ):
out = str( x ),
@@ -397,7 +397,7 @@ def _totuple( x ):
def escape( text, newline=False ):
"""Escape special html characters."""
- if isinstance( text, basestring ):
+ if isinstance( text, str ):
if '&' in text:
text = text.replace( '&', '&' )
if '>' in text:
@@ -419,7 +419,7 @@ _escape = escape
def unescape( text ):
"""Inverse of escape."""
- if isinstance( text, basestring ):
+ if isinstance( text, str ):
if '&' in text:
text = text.replace( '&', '&' )
if '>' in text:
@@ -481,4 +481,4 @@ class CustomizationError( MarkupError ):
self.message = "If you customize the allowed elements, you must define both types 'onetags' and 'twotags'."
if __name__ == '__main__':
- print __doc__
+ print(__doc__)
diff --git a/tablib/packages/ordereddict.py b/tablib/packages/ordereddict.py
index 5b0303f..a5b896d 100644
--- a/tablib/packages/ordereddict.py
+++ b/tablib/packages/ordereddict.py
@@ -1,127 +1,127 @@
-# Copyright (c) 2009 Raymond Hettinger
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction,
-# including without limitation the rights to use, copy, modify, merge,
-# publish, distribute, sublicense, and/or sell copies of the Software,
-# and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-# OTHER DEALINGS IN THE SOFTWARE.
-
-from UserDict import DictMixin
-
-class OrderedDict(dict, DictMixin):
-
- def __init__(self, *args, **kwds):
- if len(args) > 1:
- raise TypeError('expected at most 1 arguments, got %d' % len(args))
- try:
- self.__end
- except AttributeError:
- self.clear()
- self.update(*args, **kwds)
-
- def clear(self):
- self.__end = end = []
- end += [None, end, end] # sentinel node for doubly linked list
- self.__map = {} # key --> [key, prev, next]
- dict.clear(self)
-
- def __setitem__(self, key, value):
- if key not in self:
- end = self.__end
- curr = end[1]
- curr[2] = end[1] = self.__map[key] = [key, curr, end]
- dict.__setitem__(self, key, value)
-
- def __delitem__(self, key):
- dict.__delitem__(self, key)
- key, prev, next = self.__map.pop(key)
- prev[2] = next
- next[1] = prev
-
- def __iter__(self):
- end = self.__end
- curr = end[2]
- while curr is not end:
- yield curr[0]
- curr = curr[2]
-
- def __reversed__(self):
- end = self.__end
- curr = end[1]
- while curr is not end:
- yield curr[0]
- curr = curr[1]
-
- def popitem(self, last=True):
- if not self:
- raise KeyError('dictionary is empty')
- if last:
- key = reversed(self).next()
- else:
- key = iter(self).next()
- value = self.pop(key)
- return key, value
-
- def __reduce__(self):
- items = [[k, self[k]] for k in self]
- tmp = self.__map, self.__end
- del self.__map, self.__end
- inst_dict = vars(self).copy()
- self.__map, self.__end = tmp
- if inst_dict:
- return (self.__class__, (items,), inst_dict)
- return self.__class__, (items,)
-
- def keys(self):
- return list(self)
-
- setdefault = DictMixin.setdefault
- update = DictMixin.update
- pop = DictMixin.pop
- values = DictMixin.values
- items = DictMixin.items
- iterkeys = DictMixin.iterkeys
- itervalues = DictMixin.itervalues
- iteritems = DictMixin.iteritems
-
- def __repr__(self):
- if not self:
- return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, self.items())
-
- def copy(self):
- return self.__class__(self)
-
- @classmethod
- def fromkeys(cls, iterable, value=None):
- d = cls()
- for key in iterable:
- d[key] = value
- return d
-
- def __eq__(self, other):
- if isinstance(other, OrderedDict):
- if len(self) != len(other):
- return False
- for p, q in zip(self.items(), other.items()):
- if p != q:
- return False
- return True
- return dict.__eq__(self, other)
-
- def __ne__(self, other):
- return not self == other
+# Copyright (c) 2009 Raymond Hettinger
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+from UserDict import DictMixin
+
+class OrderedDict(dict, DictMixin):
+
+ def __init__(self, *args, **kwds):
+ if len(args) > 1:
+ raise TypeError('expected at most 1 arguments, got %d' % len(args))
+ try:
+ self.__end
+ except AttributeError:
+ self.clear()
+ self.update(*args, **kwds)
+
+ def clear(self):
+ self.__end = end = []
+ end += [None, end, end] # sentinel node for doubly linked list
+ self.__map = {} # key --> [key, prev, next]
+ dict.clear(self)
+
+ def __setitem__(self, key, value):
+ if key not in self:
+ end = self.__end
+ curr = end[1]
+ curr[2] = end[1] = self.__map[key] = [key, curr, end]
+ dict.__setitem__(self, key, value)
+
+ def __delitem__(self, key):
+ dict.__delitem__(self, key)
+ key, prev, next = self.__map.pop(key)
+ prev[2] = next
+ next[1] = prev
+
+ def __iter__(self):
+ end = self.__end
+ curr = end[2]
+ while curr is not end:
+ yield curr[0]
+ curr = curr[2]
+
+ def __reversed__(self):
+ end = self.__end
+ curr = end[1]
+ while curr is not end:
+ yield curr[0]
+ curr = curr[1]
+
+ def popitem(self, last=True):
+ if not self:
+ raise KeyError('dictionary is empty')
+ if last:
+ key = next(reversed(self))
+ else:
+ key = next(iter(self))
+ value = self.pop(key)
+ return key, value
+
+ def __reduce__(self):
+ items = [[k, self[k]] for k in self]
+ tmp = self.__map, self.__end
+ del self.__map, self.__end
+ inst_dict = vars(self).copy()
+ self.__map, self.__end = tmp
+ if inst_dict:
+ return (self.__class__, (items,), inst_dict)
+ return self.__class__, (items,)
+
+ def keys(self):
+ return list(self)
+
+ setdefault = DictMixin.setdefault
+ update = DictMixin.update
+ pop = DictMixin.pop
+ values = DictMixin.values
+ items = DictMixin.items
+ iterkeys = DictMixin.iterkeys
+ itervalues = DictMixin.itervalues
+ iteritems = DictMixin.iteritems
+
+ def __repr__(self):
+ if not self:
+ return '%s()' % (self.__class__.__name__,)
+ return '%s(%r)' % (self.__class__.__name__, list(self.items()))
+
+ def copy(self):
+ return self.__class__(self)
+
+ @classmethod
+ def fromkeys(cls, iterable, value=None):
+ d = cls()
+ for key in iterable:
+ d[key] = value
+ return d
+
+ def __eq__(self, other):
+ if isinstance(other, OrderedDict):
+ if len(self) != len(other):
+ return False
+ for p, q in zip(list(self.items()), list(other.items())):
+ if p != q:
+ return False
+ return True
+ return dict.__eq__(self, other)
+
+ def __ne__(self, other):
+ return not self == other