This commit is contained in:
Kenneth Reitz
2011-03-23 01:13:16 -04:00
parent 58bc1c7dcf
commit 117344de14
9 changed files with 184 additions and 183 deletions
+15 -14
View File
@@ -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
+6 -6
View File
@@ -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)
+2 -2
View File
@@ -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):
+1 -1
View File
@@ -3,7 +3,7 @@
""" Tablib - HTML export support.
"""
from StringIO import StringIO
from io import StringIO
from tablib.packages import markup
import tablib
+2 -2
View File
@@ -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):
+4 -4
View File
@@ -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()
+5 -5
View File
@@ -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)
+22 -22
View File
@@ -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 <link> 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 <script type='text/type' src=src></script>"""
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( '&', '&amp;' )
if '>' in text:
@@ -419,7 +419,7 @@ _escape = escape
def unescape( text ):
"""Inverse of escape."""
if isinstance( text, basestring ):
if isinstance( text, str ):
if '&amp;' in text:
text = text.replace( '&amp;', '&' )
if '&gt;' 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__)
+127 -127
View File
@@ -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