summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fabfile.py20
-rw-r--r--setup.py62
-rw-r--r--tablib/__init__.py4
-rw-r--r--tablib/core.py940
-rw-r--r--tablib/formats/_csv.py40
-rw-r--r--tablib/formats/_json.py50
-rw-r--r--tablib/formats/_tsv.py46
-rw-r--r--tablib/formats/_xls.py98
-rw-r--r--tablib/formats/_yaml.py52
-rw-r--r--tablib/helpers.py40
-rw-r--r--tablib/packages/markup.py82
-rwxr-xr-xtest_tablib.py606
12 files changed, 1020 insertions, 1020 deletions
diff --git a/fabfile.py b/fabfile.py
index e2b0f8d..1e25b13 100644
--- a/fabfile.py
+++ b/fabfile.py
@@ -3,15 +3,15 @@ from fabric.api import *
def scrub():
- """ Death to the bytecode! """
- local('rm -fr dist build')
- local("find . -name \"*.pyc\" -exec rm '{}' ';'")
+ """ Death to the bytecode! """
+ local('rm -fr dist build')
+ local("find . -name \"*.pyc\" -exec rm '{}' ';'")
def docs():
- """Build docs."""
- os.system('make dirhtml')
- os.chdir('_build/dirhtml')
- os.system('sphinxtogithub .')
- os.system('git add -A')
- os.system('git commit -m \'documentation update\'')
- os.system('git push origin gh-pages') \ No newline at end of file
+ """Build docs."""
+ os.system('make dirhtml')
+ os.chdir('_build/dirhtml')
+ os.system('sphinxtogithub .')
+ os.system('git add -A')
+ os.system('git commit -m \'documentation update\'')
+ os.system('git push origin gh-pages') \ No newline at end of file
diff --git a/setup.py b/setup.py
index c851751..57cee3c 100644
--- a/setup.py
+++ b/setup.py
@@ -8,43 +8,43 @@ from distutils.core import setup
def publish():
- """Publish to PyPi"""
- os.system("python setup.py sdist upload")
+ """Publish to PyPi"""
+ os.system("python setup.py sdist upload")
if sys.argv[-1] == "publish":
- publish()
- sys.exit()
+ publish()
+ sys.exit()
required = []
setup(
- name='tablib',
- version='0.9.3',
- description='Format agnostic tabular data library (XLS, JSON, YAML, CSV)',
- long_description=open('README.rst').read() + '\n\n' +
- open('HISTORY.rst').read(),
- author='Kenneth Reitz',
- author_email='me@kennethreitz.com',
- url='http://tablib.org',
- packages= [
- 'tablib', 'tablib.formats',
- 'tablib.packages',
- 'tablib.packages.simplejson',
- 'tablib.packages.xlwt',
- 'tablib.packages.yaml',
- ],
- install_requires=required,
- license='MIT',
- classifiers=(
- 'Development Status :: 5 - Production/Stable',
- 'Intended Audience :: Developers',
- 'Natural Language :: English',
- 'License :: OSI Approved :: MIT License',
- 'Programming Language :: Python',
+ name='tablib',
+ version='0.9.3',
+ description='Format agnostic tabular data library (XLS, JSON, YAML, CSV)',
+ long_description=open('README.rst').read() + '\n\n' +
+ open('HISTORY.rst').read(),
+ author='Kenneth Reitz',
+ author_email='me@kennethreitz.com',
+ url='http://tablib.org',
+ packages= [
+ 'tablib', 'tablib.formats',
+ 'tablib.packages',
+ 'tablib.packages.simplejson',
+ 'tablib.packages.xlwt',
+ 'tablib.packages.yaml',
+ ],
+ install_requires=required,
+ license='MIT',
+ classifiers=(
+ 'Development Status :: 5 - Production/Stable',
+ 'Intended Audience :: Developers',
+ 'Natural Language :: English',
+ 'License :: OSI Approved :: MIT License',
+ 'Programming Language :: Python',
# 'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
- 'Programming Language :: Python :: 2.7',
- # 'Programming Language :: Python :: 3.0',
- # 'Programming Language :: Python :: 3.1',
- ),
+ 'Programming Language :: Python :: 2.7',
+ # 'Programming Language :: Python :: 3.0',
+ # 'Programming Language :: Python :: 3.1',
+ ),
)
diff --git a/tablib/__init__.py b/tablib/__init__.py
index 3f23850..c2205b6 100644
--- a/tablib/__init__.py
+++ b/tablib/__init__.py
@@ -2,7 +2,7 @@
"""
from tablib.core import (
- Databook, Dataset, detect, import_set,
- InvalidDatasetType, InvalidDimensions, UnsupportedFormat
+ Databook, Dataset, detect, import_set,
+ InvalidDatasetType, InvalidDimensions, UnsupportedFormat
)
diff --git a/tablib/core.py b/tablib/core.py
index a42f1f8..78c7481 100644
--- a/tablib/core.py
+++ b/tablib/core.py
@@ -24,73 +24,73 @@ __copyright__ = 'Copyright 2011 Kenneth Reitz'
class Row(object):
- """Internal Row object. Mainly used for filtering."""
+ """Internal Row object. Mainly used for filtering."""
- __slots__ = ['tuple', '_row', 'tags']
+ __slots__ = ['tuple', '_row', 'tags']
- def __init__(self, row=list(), tags=list()):
- self._row = list(row)
- self.tags = list(tags)
+ def __init__(self, row=list(), tags=list()):
+ self._row = list(row)
+ self.tags = list(tags)
- def __iter__(self):
- return (col for col in self._row)
+ def __iter__(self):
+ return (col for col in self._row)
- def __len__(self):
- return len(self._row)
+ def __len__(self):
+ return len(self._row)
- def __repr__(self):
- return repr(self._row)
+ def __repr__(self):
+ return repr(self._row)
- def __getslice__(self, i, j):
- return self._row[i,j]
+ def __getslice__(self, i, j):
+ return self._row[i,j]
- def __getitem__(self, i):
- return self._row[i]
+ def __getitem__(self, i):
+ return self._row[i]
- def __setitem__(self, i, value):
- self._row[i] = value
+ def __setitem__(self, i, value):
+ self._row[i] = value
- def __delitem__(self, i):
- del self._row[i]
+ def __delitem__(self, i):
+ del self._row[i]
- def __getstate__(self):
- return {slot: [getattr(self, slot) for slot in self.__slots__]}
+ def __getstate__(self):
+ return {slot: [getattr(self, slot) for slot in self.__slots__]}
- def __setstate__(self, state):
- for (k, v) in state.items(): setattr(self, k, v)
+ def __setstate__(self, state):
+ for (k, v) in state.items(): setattr(self, k, v)
- def append(self, value):
- self._row.append(value)
+ def append(self, value):
+ self._row.append(value)
- def insert(self, index, value):
- self._row.insert(index, value)
+ def insert(self, index, value):
+ self._row.insert(index, value)
- def __contains__(self, item):
- return (item in self._row)
+ def __contains__(self, item):
+ return (item in self._row)
- @property
- def tuple(self):
- '''Tuple representation of :class:`Row`.'''
- return tuple(self._row)
+ @property
+ def tuple(self):
+ '''Tuple representation of :class:`Row`.'''
+ return tuple(self._row)
- @property
- def list(self):
- '''List representation of :class:`Row`.'''
- return list(self._row)
+ @property
+ def list(self):
+ '''List representation of :class:`Row`.'''
+ return list(self._row)
- def has_tag(self, tag):
- """Returns true if current row contains tag."""
+ def has_tag(self, tag):
+ """Returns true if current row contains tag."""
- if tag == None:
- return False
- elif isinstance(tag, basestring):
- return (tag in self.tags)
- else:
- return True if len(set(tag) & set(self.tags)) else False
+ if tag == None:
+ return False
+ elif isinstance(tag, basestring):
+ return (tag in self.tags)
+ else:
+ return True if len(set(tag) & set(self.tags)) else False
class Dataset(object):
- """The :class:`Dataset` object is the heart of Tablib. It provides all core
+ """The :class:`Dataset` object is the heart of Tablib. It provides all core
functionality.
Usually you create a :class:`Dataset` instance in your main module, and append
@@ -121,189 +121,189 @@ class Dataset(object):
defined within the :class:`Dataset` object. To add support for a new format, see
:ref:`Adding New Formats <newformats>`.
- """
+ """
- def __init__(self, *args, **kwargs):
- self._data = list(Row(arg) for arg in args)
- self.__headers = None
+ def __init__(self, *args, **kwargs):
+ self._data = list(Row(arg) for arg in args)
+ self.__headers = None
- # ('title', index) tuples
- self._separators = []
+ # ('title', index) tuples
+ self._separators = []
- try:
- self.headers = kwargs['headers']
- except KeyError:
- self.headers = None
+ try:
+ self.headers = kwargs['headers']
+ except KeyError:
+ self.headers = None
- try:
- self.title = kwargs['title']
- except KeyError:
- self.title = None
+ try:
+ self.title = kwargs['title']
+ except KeyError:
+ self.title = None
- self._register_formats()
+ self._register_formats()
- def __len__(self):
- return self.height
+ def __len__(self):
+ return self.height
- def __getitem__(self, 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]
- else:
- raise KeyError
- else:
- _results = self._data[key]
- if isinstance(_results, Row):
- return _results.tuple
- else:
- return [result.tuple for result in _results]
+ def __getitem__(self, 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]
+ else:
+ raise KeyError
+ else:
+ _results = self._data[key]
+ if isinstance(_results, Row):
+ return _results.tuple
+ else:
+ return [result.tuple for result in _results]
- def __setitem__(self, key, value):
- self._validate(value)
- self._data[key] = Row(value)
+ def __setitem__(self, key, value):
+ self._validate(value)
+ self._data[key] = Row(value)
- def __delitem__(self, key):
- if isinstance(key, basestring):
+ def __delitem__(self, key):
+ if isinstance(key, basestring):
- if key in self.headers:
+ if key in self.headers:
- pos = self.headers.index(key)
- del self.headers[pos]
+ pos = self.headers.index(key)
+ del self.headers[pos]
- for i, row in enumerate(self._data):
+ for i, row in enumerate(self._data):
- del row[pos]
- self._data[i] = row
- else:
- raise KeyError
- else:
- del self._data[key]
+ del row[pos]
+ self._data[i] = row
+ else:
+ raise KeyError
+ else:
+ del self._data[key]
- def __repr__(self):
- try:
- return '<%s dataset>' % (self.title.lower())
- except AttributeError:
- return '<dataset object>'
+ def __repr__(self):
+ try:
+ return '<%s dataset>' % (self.title.lower())
+ except AttributeError:
+ return '<dataset object>'
- @classmethod
- def _register_formats(cls):
- """Adds format properties."""
- for fmt in formats.available:
- try:
- try:
- setattr(cls, fmt.title, property(fmt.export_set, fmt.import_set))
- except AttributeError:
- setattr(cls, fmt.title, property(fmt.export_set))
+ @classmethod
+ def _register_formats(cls):
+ """Adds format properties."""
+ for fmt in formats.available:
+ 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
+ except AttributeError:
+ pass
- def _validate(self, row=None, col=None, safety=False):
- """Assures size of every row in dataset is of proper proportions."""
- if row:
- is_valid = (len(row) == self.width) if self.width else True
- elif col:
- if len(col) < 1:
- is_valid = True
- else:
- is_valid = (len(col) == self.height) if self.height else True
- else:
- is_valid = all((len(x) == self.width for x in self._data))
+ def _validate(self, row=None, col=None, safety=False):
+ """Assures size of every row in dataset is of proper proportions."""
+ if row:
+ is_valid = (len(row) == self.width) if self.width else True
+ elif col:
+ if len(col) < 1:
+ is_valid = True
+ else:
+ is_valid = (len(col) == self.height) if self.height else True
+ else:
+ is_valid = all((len(x) == self.width for x in self._data))
- if is_valid:
- return True
- else:
- if not safety:
- raise InvalidDimensions
- return False
+ if is_valid:
+ return True
+ else:
+ if not safety:
+ raise InvalidDimensions
+ return False
- def _package(self, dicts=True):
- """Packages Dataset into lists of dictionaries for transmission."""
+ def _package(self, dicts=True):
+ """Packages Dataset into lists of dictionaries for transmission."""
- if self.headers:
- if dicts:
- data = [dict(zip(self.headers, data_row)) for data_row in self ._data]
- else:
- data = [list(self.headers)] + list(self._data)
- else:
- data = [list(row) for row in self._data]
+ if self.headers:
+ if dicts:
+ data = [dict(zip(self.headers, data_row)) for data_row in self ._data]
+ else:
+ data = [list(self.headers)] + list(self._data)
+ else:
+ data = [list(row) for row in self._data]
- return data
+ return data
- def _clean_col(self, col):
- """Prepares the given column for insert/append."""
+ def _clean_col(self, col):
+ """Prepares the given column for insert/append."""
- col = list(col)
+ col = list(col)
- if self.headers:
- header = [col.pop(0)]
- else:
- header = []
+ if self.headers:
+ header = [col.pop(0)]
+ else:
+ header = []
- if len(col) == 1 and callable(col[0]):
- col = map(col[0], self._data)
- col = tuple(header + col)
+ if len(col) == 1 and callable(col[0]):
+ col = map(col[0], self._data)
+ col = tuple(header + col)
- return col
+ return col
- @property
- def height(self):
- """The number of rows currently in the :class:`Dataset`.
- Cannot be directly modified.
- """
- return len(self._data)
+ @property
+ def height(self):
+ """The number of rows currently in the :class:`Dataset`.
+ Cannot be directly modified.
+ """
+ return len(self._data)
- @property
- def width(self):
- """The number of columns currently in the :class:`Dataset`.
- Cannot be directly modified.
- """
+ @property
+ def width(self):
+ """The number of columns currently in the :class:`Dataset`.
+ Cannot be directly modified.
+ """
- try:
- return len(self._data[0])
- except IndexError:
- try:
- return len(self.headers)
- except TypeError:
- return 0
+ try:
+ return len(self._data[0])
+ except IndexError:
+ try:
+ return len(self.headers)
+ except TypeError:
+ return 0
- def _get_headers(self):
- """An *optional* list of strings to be used for header rows and attribute names.
+ def _get_headers(self):
+ """An *optional* list of strings to be used for header rows and attribute names.
This must be set manually. The given list length must equal :class:`Dataset.width`.
- """
- return self.__headers
+ """
+ return self.__headers
- def _set_headers(self, collection):
- """Validating headers setter."""
- self._validate(collection)
- if collection:
- try:
- self.__headers = list(collection)
- except TypeError:
- raise TypeError
- else:
- self.__headers = None
+ def _set_headers(self, collection):
+ """Validating headers setter."""
+ self._validate(collection)
+ if collection:
+ try:
+ self.__headers = list(collection)
+ except TypeError:
+ raise TypeError
+ else:
+ self.__headers = None
- headers = property(_get_headers, _set_headers)
+ headers = property(_get_headers, _set_headers)
- def _get_dict(self):
- """A JSON representation of the :class:`Dataset` object. If headers have been
+ def _get_dict(self):
+ """A JSON representation of the :class:`Dataset` object. If headers have been
set, a JSON list of objects will be returned. If no headers have
been set, a JSON list of lists (rows) will be returned instead.
@@ -312,155 +312,155 @@ class Dataset(object):
data = tablib.Dataset()
data.json = '[{"last_name": "Adams","age": 90,"first_name": "John"}]'
- """
- return self._package()
+ """
+ return self._package()
- def _set_dict(self, pickle):
- """A native Python representation of the Dataset object. If headers have been
- set, a list of Python dictionaries will be returned. If no headers have been
- set, a list of tuples (rows) will be returned instead.
+ def _set_dict(self, pickle):
+ """A native Python representation of the Dataset object. If headers have been
+ set, a list of Python dictionaries will be returned. If no headers have been
+ set, a list of tuples (rows) will be returned instead.
- A dataset object can also be imported by setting the :class:`Dataset.dict` attribute. ::
+ A dataset object can also be imported by setting the :class:`Dataset.dict` attribute. ::
- data = tablib.Dataset()
- data.dict = [{'age': 90, 'first_name': 'Kenneth', 'last_name': 'Reitz'}]
+ data = tablib.Dataset()
+ data.dict = [{'age': 90, 'first_name': 'Kenneth', 'last_name': 'Reitz'}]
- """
- if not len(pickle):
- return
+ """
+ if not len(pickle):
+ return
- # if list of rows
- if isinstance(pickle[0], list):
- self.wipe()
- for row in pickle:
- self.append(Row(row))
+ # if list of rows
+ if isinstance(pickle[0], list):
+ self.wipe()
+ for row in pickle:
+ self.append(Row(row))
- # if list of objects
- elif isinstance(pickle[0], dict):
- self.wipe()
- self.headers = pickle[0].keys()
- for row in pickle:
- self.append(Row(row.values()))
- else:
- raise UnsupportedFormat
+ # if list of objects
+ elif isinstance(pickle[0], dict):
+ self.wipe()
+ self.headers = pickle[0].keys()
+ for row in pickle:
+ self.append(Row(row.values()))
+ else:
+ raise UnsupportedFormat
- dict = property(_get_dict, _set_dict)
+ dict = property(_get_dict, _set_dict)
- @property
- def xls():
- """An Excel Spreadsheet representation of the :class:`Dataset` object, with :ref:`seperators`. Cannot be set.
+ @property
+ def xls():
+ """An Excel Spreadsheet representation of the :class:`Dataset` object, with :ref:`seperators`. Cannot be set.
- .. admonition:: Binary Warning
+ .. admonition:: Binary Warning
- :class:`Dataset.xls` contains binary data, so make sure to write in binary mode::
+ :class:`Dataset.xls` contains binary data, so make sure to write in binary mode::
- with open('output.xls', 'wb') as f:
- f.write(data.xls)'
- """
- pass
+ with open('output.xls', 'wb') as f:
+ f.write(data.xls)'
+ """
+ pass
- @property
- def csv():
- """A CSV representation of the :class:`Dataset` object. The top row will contain
- headers, if they have been set. Otherwise, the top row will contain
- the first row of the dataset.
+ @property
+ def csv():
+ """A CSV representation of the :class:`Dataset` object. The top row will contain
+ headers, if they have been set. Otherwise, the top row will contain
+ the first row of the dataset.
- A dataset object can also be imported by setting the :class:`Dataset.csv` attribute. ::
+ A dataset object can also be imported by setting the :class:`Dataset.csv` attribute. ::
- data = tablib.Dataset()
- data.csv = 'age, first_name, last_name\\n90, John, Adams'
+ data = tablib.Dataset()
+ data.csv = 'age, first_name, last_name\\n90, John, Adams'
- Import assumes (for now) that headers exist.
- """
- pass
+ Import assumes (for now) that headers exist.
+ """
+ pass
- @property
- def tsv():
- """A TSV representation of the :class:`Dataset` object. The top row will contain
- headers, if they have been set. Otherwise, the top row will contain
- the first row of the dataset.
+ @property
+ def tsv():
+ """A TSV representation of the :class:`Dataset` object. The top row will contain
+ headers, if they have been set. Otherwise, the top row will contain
+ the first row of the dataset.
- A dataset object can also be imported by setting the :class:`Dataset.tsv` attribute. ::
+ A dataset object can also be imported by setting the :class:`Dataset.tsv` attribute. ::
- data = tablib.Dataset()
- data.tsv = 'age\tfirst_name\tlast_name\\n90\tJohn\tAdams'
+ data = tablib.Dataset()
+ data.tsv = 'age\tfirst_name\tlast_name\\n90\tJohn\tAdams'
- Import assumes (for now) that headers exist.
- """
+ Import assumes (for now) that headers exist.
+ """
- @property
- def yaml():
- """A YAML representation of the :class:`Dataset` object. If headers have been
- set, a YAML list of objects will be returned. If no headers have
- been set, a YAML list of lists (rows) will be returned instead.
+ @property
+ def yaml():
+ """A YAML representation of the :class:`Dataset` object. If headers have been
+ set, a YAML list of objects will be returned. If no headers have
+ been set, a YAML list of lists (rows) will be returned instead.
- A dataset object can also be imported by setting the :class:`Dataset.json` attribute: ::
+ A dataset object can also be imported by setting the :class:`Dataset.json` attribute: ::
- data = tablib.Dataset()
- data.yaml = '- {age: 90, first_name: John, last_name: Adams}'
+ data = tablib.Dataset()
+ data.yaml = '- {age: 90, first_name: John, last_name: Adams}'
- Import assumes (for now) that headers exist.
- """
- pass
+ Import assumes (for now) that headers exist.
+ """
+ pass
- @property
- def json():
- """A JSON representation of the :class:`Dataset` object. If headers have been
- set, a JSON list of objects will be returned. If no headers have
- been set, a JSON list of lists (rows) will be returned instead.
+ @property
+ def json():
+ """A JSON representation of the :class:`Dataset` object. If headers have been
+ set, a JSON list of objects will be returned. If no headers have
+ been set, a JSON list of lists (rows) will be returned instead.
- A dataset object can also be imported by setting the :class:`Dataset.json` attribute: ::
+ A dataset object can also be imported by setting the :class:`Dataset.json` attribute: ::
- data = tablib.Dataset()
- data.json = '[{age: 90, first_name: "John", liast_name: "Adams"}]'
+ data = tablib.Dataset()
+ data.json = '[{age: 90, first_name: "John", liast_name: "Adams"}]'
- Import assumes (for now) that headers exist.
- """
+ Import assumes (for now) that headers exist.
+ """
- @property
- def html():
- """A HTML table representation of the :class:`Dataset` object. If
- headers have been set, they will be used as table headers.
+ @property
+ def html():
+ """A HTML table representation of the :class:`Dataset` object. If
+ headers have been set, they will be used as table headers.
- ..notice:: This method can be used for export only.
- """
- pass
+ ..notice:: This method can be used for export only.
+ """
+ pass
- def append(self, row=None, col=None, header=None, tags=list()):
- """Adds a row or column to the :class:`Dataset`.
- Usage is :class:`Dataset.insert` for documentation.
+ def append(self, row=None, col=None, header=None, tags=list()):
+ """Adds a row or column to the :class:`Dataset`.
+ Usage is :class:`Dataset.insert` for documentation.
"""
- if row is not None:
- self.insert(self.height, row=row, tags=tags)
- elif col is not None:
- self.insert(self.width, col=col, header=header)
+ if row is not None:
+ self.insert(self.height, row=row, tags=tags)
+ elif col is not None:
+ self.insert(self.width, col=col, header=header)
- def insert_separator(self, index, text='-'):
- """Adds a separator to :class:`Dataset` at given index."""
+ def insert_separator(self, index, text='-'):
+ """Adds a separator to :class:`Dataset` at given index."""
- sep = (index, text)
- self._separators.append(sep)
+ sep = (index, text)
+ self._separators.append(sep)
- def append_separator(self, text='-'):
- """Adds a :ref:`seperator <seperators>` to the :class:`Dataset`."""
+ def append_separator(self, text='-'):
+ """Adds a :ref:`seperator <seperators>` to the :class:`Dataset`."""
- # change offsets if headers are or aren't defined
- if not self.headers:
- index = self.height if self.height else 0
- else:
- index = (self.height + 1) if self.height else 1
+ # change offsets if headers are or aren't defined
+ if not self.headers:
+ index = self.height if self.height else 0
+ else:
+ index = (self.height + 1) if self.height else 1
- self.insert_separator(index, text)
+ self.insert_separator(index, text)
- def insert(self, index, row=None, col=None, header=None, tags=list()):
- """Inserts a row or column to the :class:`Dataset` at the given index.
+ def insert(self, index, row=None, col=None, header=None, tags=list()):
+ """Inserts a row or column to the :class:`Dataset` at the given index.
Rows and columns inserted must be the correct size (height or width).
@@ -486,270 +486,270 @@ class Dataset(object):
This gives you the ability to :class:`filter <Dataset.filter>` your
:class:`Dataset` later.
- """
- if row:
- self._validate(row)
- self._data.insert(index, Row(row, tags=tags))
- elif col:
- col = list(col)
+ """
+ if row:
+ self._validate(row)
+ self._data.insert(index, Row(row, tags=tags))
+ elif col:
+ col = list(col)
- # Callable Columns...
- if len(col) == 1 and callable(col[0]):
- col = map(col[0], self._data)
+ # Callable Columns...
+ if len(col) == 1 and callable(col[0]):
+ col = map(col[0], self._data)
- col = self._clean_col(col)
- self._validate(col=col)
+ col = self._clean_col(col)
+ self._validate(col=col)
- if self.headers:
- # pop the first item off, add to headers
- if not header:
- raise HeadersNeeded()
- self.headers.insert(index, header)
+ if self.headers:
+ # pop the first item off, add to headers
+ if not header:
+ raise HeadersNeeded()
+ self.headers.insert(index, header)
- if self.height and self.width:
+ if self.height and self.width:
- for i, row in enumerate(self._data):
+ for i, row in enumerate(self._data):
- row.insert(index, col[i])
- self._data[i] = row
- else:
- self._data = [Row([row]) for row in col]
+ row.insert(index, col[i])
+ self._data[i] = row
+ else:
+ self._data = [Row([row]) for row in col]
- def filter(self, tag):
- """Returns a new instance of the :class:`Dataset`, excluding any rows
- that do not contain the given :ref:`tags <tags>`.
- """
- _dset = copy(self)
- _dset._data = [row for row in _dset._data if row.has_tag(tag)]
+ def filter(self, tag):
+ """Returns a new instance of the :class:`Dataset`, excluding any rows
+ that do not contain the given :ref:`tags <tags>`.
+ """
+ _dset = copy(self)
+ _dset._data = [row for row in _dset._data if row.has_tag(tag)]
- return _dset
+ return _dset
- def sort(self, col, reverse=False):
- """Sort a :class:`Dataset` by a specific column, given string (for
- header) or integer (for column index). The order can be reversed by
- setting ``reverse`` to ``True``.
- Returns a new :class:`Dataset` instance where columns have been
- sorted."""
-
- if isinstance(col, basestring):
+ def sort(self, col, reverse=False):
+ """Sort a :class:`Dataset` by a specific column, given string (for
+ header) or integer (for column index). The order can be reversed by
+ setting ``reverse`` to ``True``.
+ Returns a new :class:`Dataset` instance where columns have been
+ sorted."""
+
+ if isinstance(col, basestring):
- if not self.headers:
- raise HeadersNeeded
+ if not self.headers:
+ raise HeadersNeeded
- _sorted = sorted(self.dict, key=itemgetter(col), reverse=reverse)
- _dset = Dataset(headers=self.headers)
+ _sorted = sorted(self.dict, key=itemgetter(col), reverse=reverse)
+ _dset = Dataset(headers=self.headers)
- for item in _sorted:
- row = [item[key] for key in self.headers]
- _dset.append(row=row)
+ for item in _sorted:
+ row = [item[key] for key in self.headers]
+ _dset.append(row=row)
- else:
- if self.headers:
- col = self.headers[col]
+ else:
+ if self.headers:
+ col = self.headers[col]
- _sorted = sorted(self.dict, key=itemgetter(col), reverse=reverse)
- _dset = Dataset(headers=self.headers)
+ _sorted = sorted(self.dict, key=itemgetter(col), reverse=reverse)
+ _dset = Dataset(headers=self.headers)
- for item in _sorted:
- if self.headers:
- row = [item[key] for key in self.headers]
- else:
- row = item
- _dset.append(row=row)
+ for item in _sorted:
+ if self.headers:
+ row = [item[key] for key in self.headers]
+ else:
+ row = item
+ _dset.append(row=row)
- return _dset
+ return _dset
- def transpose(self):
- """Transpose a :class:`Dataset`, turning rows into columns and vice
- versa, returning a new ``Dataset`` instance. The first row of the
- original instance becomes the new header row."""
+ def transpose(self):
+ """Transpose a :class:`Dataset`, turning rows into columns and vice
+ versa, returning a new ``Dataset`` instance. The first row of the
+ original instance becomes the new header row."""
- # Don't transpose if there is no data
- if not self:
- return
+ # Don't transpose if there is no data
+ if not self:
+ return
- _dset = Dataset()
- # The first element of the headers stays in the headers,
- # it is our "hinge" on which we rotate the data
- new_headers = [self.headers[0]] + self[self.headers[0]]
+ _dset = Dataset()
+ # The first element of the headers stays in the headers,
+ # it is our "hinge" on which we rotate the data
+ new_headers = [self.headers[0]] + self[self.headers[0]]
- _dset.headers = new_headers
- for column in self.headers:
+ _dset.headers = new_headers
+ for column in self.headers:
- if column == self.headers[0]:
- # It's in the headers, so skip it
- continue
+ if column == self.headers[0]:
+ # It's in the headers, so skip it
+ continue
- # Adding the column name as now they're a regular column
- row_data = [column] + self[column]
- row_data = Row(row_data)
- _dset.append(row=row_data)
+ # Adding the column name as now they're a regular column
+ row_data = [column] + self[column]
+ row_data = Row(row_data)
+ _dset.append(row=row_data)
- return _dset
+ return _dset
- def stack_rows(self, other):
- """Stack two :class:`Dataset` instances together by
- joining at the row level, and return new combined
- ``Dataset`` instance."""
+ def stack_rows(self, other):
+ """Stack two :class:`Dataset` instances together by
+ joining at the row level, and return new combined
+ ``Dataset`` instance."""
- if not isinstance(other, Dataset):
- return
+ if not isinstance(other, Dataset):
+ return
- if self.width != other.width:
- raise InvalidDimensions
+ if self.width != other.width:
+ raise InvalidDimensions
- # Copy the source data
- _dset = copy(self)
+ # Copy the source data
+ _dset = copy(self)
- rows_to_stack = [row for row in _dset._data]
- other_rows = [row for row in other._data]
+ rows_to_stack = [row for row in _dset._data]
+ other_rows = [row for row in other._data]
- rows_to_stack.extend(other_rows)
- _dset._data = rows_to_stack
+ rows_to_stack.extend(other_rows)
+ _dset._data = rows_to_stack
- return _dset
+ return _dset
- def stack_columns(self, other):
- """Stack two :class:`Dataset` instances together by
- joining at the column level, and return a new
- combined ``Dataset`` instance. If either ``Dataset``
- has headers set, than the other must as well."""
+ def stack_columns(self, other):
+ """Stack two :class:`Dataset` instances together by
+ joining at the column level, and return a new
+ combined ``Dataset`` instance. If either ``Dataset``
+ has headers set, than the other must as well."""
- if not isinstance(other, Dataset):
- return
+ if not isinstance(other, Dataset):
+ return
- if self.headers or other.headers:
- if not self.headers or not other.headers:
- raise HeadersNeeded
+ if self.headers or other.headers:
+ if not self.headers or not other.headers:
+ raise HeadersNeeded
- if self.height != other.height:
- raise InvalidDimensions
+ if self.height != other.height:
+ raise InvalidDimensions
- try:
- new_headers = self.headers + other.headers
- except TypeError:
- new_headers = None
+ try:
+ new_headers = self.headers + other.headers
+ except TypeError:
+ new_headers = None
- _dset = Dataset()
+ _dset = Dataset()
- for column in self.headers:
- _dset.append(col=self[column])
+ for column in self.headers:
+ _dset.append(col=self[column])
- for column in other.headers:
- _dset.append(col=other[column])
+ for column in other.headers:
+ _dset.append(col=other[column])
- _dset.headers = new_headers
+ _dset.headers = new_headers
- return _dset
+ return _dset
- def wipe(self):
- """Removes all content and headers from the :class:`Dataset` object."""
- self._data = list()
- self.__headers = None
+ def wipe(self):
+ """Removes all content and headers from the :class:`Dataset` object."""
+ self._data = list()
+ self.__headers = None
class Databook(object):
- """A book of :class:`Dataset` objects.
- """
+ """A book of :class:`Dataset` objects.
+ """
- def __init__(self, sets=None):
+ def __init__(self, sets=None):
- if sets is None:
- self._datasets = list()
- else:
- self._datasets = sets
+ if sets is None:
+ self._datasets = list()
+ else:
+ self._datasets = sets
- self._register_formats()
+ self._register_formats()
- def __repr__(self):
- try:
- return '<%s databook>' % (self.title.lower())
- except AttributeError:
- return '<databook object>'
+ def __repr__(self):
+ try:
+ return '<%s databook>' % (self.title.lower())
+ except AttributeError:
+ return '<databook object>'
- def wipe(self):
- """Removes all :class:`Dataset` objects from the :class:`Databook`."""
- self._datasets = []
+ def wipe(self):
+ """Removes all :class:`Dataset` objects from the :class:`Databook`."""
+ self._datasets = []
- @classmethod
- def _register_formats(cls):
- """Adds format properties."""
- for fmt in formats.available:
- try:
- try:
- setattr(cls, fmt.title, property(fmt.export_book, fmt.import_book))
- except AttributeError:
- setattr(cls, fmt.title, property(fmt.export_book))
+ @classmethod
+ def _register_formats(cls):
+ """Adds format properties."""
+ for fmt in formats.available:
+ 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
+ except AttributeError:
+ pass
- def add_sheet(self, dataset):
- """Adds given :class:`Dataset` to the :class:`Databook`."""
- if type(dataset) is Dataset:
- self._datasets.append(dataset)
- else:
- raise InvalidDatasetType
+ def add_sheet(self, dataset):
+ """Adds given :class:`Dataset` to the :class:`Databook`."""
+ if type(dataset) is Dataset:
+ self._datasets.append(dataset)
+ else:
+ raise InvalidDatasetType
- def _package(self):
- """Packages :class:`Databook` for delivery."""
- collector = []
- for dset in self._datasets:
- collector.append(dict(
- title = dset.title,
- data = dset.dict
- ))
- return collector
+ def _package(self):
+ """Packages :class:`Databook` for delivery."""
+ collector = []
+ for dset in self._datasets:
+ collector.append(dict(
+ title = dset.title,
+ data = dset.dict
+ ))
+ return collector
- @property
- def size(self):
- """The number of the :class:`Dataset` objects within :class:`Databook`."""
- return len(self._datasets)
+ @property
+ def size(self):
+ """The number of the :class:`Dataset` objects within :class:`Databook`."""
+ return len(self._datasets)
def detect(stream):
- """Return (format, stream) of given stream."""
- for fmt in formats.available:
- try:
- if fmt.detect(stream):
- return (fmt, stream)
- except AttributeError:
- pass
- return (None, stream)
+ """Return (format, stream) of given stream."""
+ for fmt in formats.available:
+ try:
+ if fmt.detect(stream):
+ return (fmt, stream)
+ except AttributeError:
+ pass
+ return (None, stream)
def import_set(stream):
- """Return dataset of given stream."""
- (format, stream) = detect(stream)
+ """Return dataset of given stream."""
+ (format, stream) = detect(stream)
- try:
- data = Dataset()
- format.import_set(data, stream)
- return data
+ try:
+ data = Dataset()
+ format.import_set(data, stream)
+ return data
- except AttributeError, e:
- return None
+ except AttributeError, e:
+ return None
class InvalidDatasetType(Exception):
- "Only Datasets can be added to a DataBook"
+ "Only Datasets can be added to a DataBook"
class InvalidDimensions(Exception):
- "Invalid size"
+ "Invalid size"
class HeadersNeeded(Exception):
- "Header parameter must be given when appending a column in this Dataset."
+ "Header parameter must be given when appending a column in this Dataset."
class UnsupportedFormat(NotImplementedError):
- "Format is not supported"
+ "Format is not supported"
diff --git a/tablib/formats/_csv.py b/tablib/formats/_csv.py
index 2391417..2c74a1c 100644
--- a/tablib/formats/_csv.py
+++ b/tablib/formats/_csv.py
@@ -16,34 +16,34 @@ extentions = ('csv',)
def export_set(dataset):
- """Returns CSV representation of Dataset."""
- stream = cStringIO.StringIO()
- _csv = csv.writer(stream)
+ """Returns CSV representation of Dataset."""
+ stream = cStringIO.StringIO()
+ _csv = csv.writer(stream)
- for row in dataset._package(dicts=False):
- _csv.writerow(row)
+ for row in dataset._package(dicts=False):
+ _csv.writerow(row)
- return stream.getvalue()
+ return stream.getvalue()
def import_set(dset, in_stream, headers=True):
- """Returns dataset from CSV stream."""
+ """Returns dataset from CSV stream."""
- dset.wipe()
+ dset.wipe()
- rows = csv.reader(in_stream.split())
- for i, row in enumerate(rows):
+ rows = csv.reader(in_stream.split())
+ for i, row in enumerate(rows):
- if (i == 0) and (headers):
- dset.headers = row
- else:
- dset.append(row)
+ if (i == 0) and (headers):
+ dset.headers = row
+ else:
+ dset.append(row)
def detect(stream):
- """Returns True if given stream is valid CSV."""
- try:
- rows = dialect = csv.Sniffer().sniff(stream)
- return True
- except csv.Error:
- return False \ No newline at end of file
+ """Returns True if given stream is valid CSV."""
+ try:
+ rows = dialect = csv.Sniffer().sniff(stream)
+ return True
+ except csv.Error:
+ return False \ No newline at end of file
diff --git a/tablib/formats/_json.py b/tablib/formats/_json.py
index 7f31ee5..51cc207 100644
--- a/tablib/formats/_json.py
+++ b/tablib/formats/_json.py
@@ -4,12 +4,12 @@
"""
try:
- import json # load system JSON (Python >= 2.6)
+ import json # load system JSON (Python >= 2.6)
except ImportError:
- try:
- import simplejson as json
- except ImportError:
- import tablib.packages.simplejson as json # use the vendorized copy
+ try:
+ import simplejson as json
+ except ImportError:
+ import tablib.packages.simplejson as json # use the vendorized copy
import tablib.core
@@ -19,37 +19,37 @@ extentions = ('json', 'jsn')
def export_set(dataset):
- """Returns JSON representation of Dataset."""
- return json.dumps(dataset.dict)
+ """Returns JSON representation of Dataset."""
+ return json.dumps(dataset.dict)
def export_book(databook):
- """Returns JSON representation of Databook."""
- return json.dumps(databook._package())
+ """Returns JSON representation of Databook."""
+ return json.dumps(databook._package())
def import_set(dset, in_stream):
- """Returns dataset from JSON stream."""
+ """Returns dataset from JSON stream."""
- dset.wipe()
- dset.dict = json.loads(in_stream)
+ dset.wipe()
+ dset.dict = json.loads(in_stream)
def import_book(dbook, in_stream):
- """Returns databook from JSON 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)
+ 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)
def detect(stream):
- """Returns True if given stream is valid JSON."""
- try:
- json.loads(stream)
- return True
- except ValueError:
- return False
+ """Returns True if given stream is valid JSON."""
+ try:
+ json.loads(stream)
+ return True
+ except ValueError:
+ return False
diff --git a/tablib/formats/_tsv.py b/tablib/formats/_tsv.py
index 808f202..76a5f07 100644
--- a/tablib/formats/_tsv.py
+++ b/tablib/formats/_tsv.py
@@ -16,36 +16,36 @@ extentions = ('tsv',)
def export_set(dataset):
- """Returns a TSV representation of Dataset."""
- stream = cStringIO.StringIO()
- _tsv = csv.writer(stream, delimiter='\t')
+ """Returns a TSV representation of Dataset."""
+ stream = cStringIO.StringIO()
+ _tsv = csv.writer(stream, delimiter='\t')
- for row in dataset._package(dicts=False):
- _tsv.writerow(row)
+ for row in dataset._package(dicts=False):
+ _tsv.writerow(row)
- return stream.getvalue()
+ return stream.getvalue()
def import_set(dset, in_stream, headers=True):
- """Returns dataset from TSV stream."""
- dset.wipe()
+ """Returns dataset from TSV stream."""
+ dset.wipe()
- rows = csv.reader(in_stream.split('\r\n'), delimiter='\t')
- for i, row in enumerate(rows):
- # Skip empty rows
- if not row:
- continue
+ rows = csv.reader(in_stream.split('\r\n'), delimiter='\t')
+ for i, row in enumerate(rows):
+ # Skip empty rows
+ if not row:
+ continue
- if (i == 0) and (headers):
- dset.headers = row
- else:
- dset.append(row)
+ if (i == 0) and (headers):
+ dset.headers = row
+ else:
+ dset.append(row)
def detect(stream):
- """Returns True if given stream is valid TSV."""
- try:
- rows = dialect = csv.Sniffer().sniff(stream, delimiters='\t')
- return True
- except csv.Error:
- return False
+ """Returns True if given stream is valid TSV."""
+ try:
+ rows = dialect = csv.Sniffer().sniff(stream, delimiters='\t')
+ return True
+ except csv.Error:
+ return False
diff --git a/tablib/formats/_xls.py b/tablib/formats/_xls.py
index 08bc0f6..717a6d5 100644
--- a/tablib/formats/_xls.py
+++ b/tablib/formats/_xls.py
@@ -6,9 +6,9 @@
import cStringIO
try:
- import xlwt
+ import xlwt
except ImportError:
- import tablib.packages.xlwt as xlwt
+ import tablib.packages.xlwt as xlwt
title = 'xls'
@@ -20,66 +20,66 @@ bold = xlwt.easyxf("font: bold on")
def export_set(dataset):
- """Returns XLS representation of Dataset."""
+ """Returns XLS representation of Dataset."""
- wb = xlwt.Workbook(encoding='utf8')
- ws = wb.add_sheet(dataset.title if dataset.title else 'Tabbed Dataset')
+ wb = xlwt.Workbook(encoding='utf8')
+ ws = wb.add_sheet(dataset.title if dataset.title else 'Tabbed Dataset')
- dset_sheet(dataset, ws)
+ dset_sheet(dataset, ws)
- stream = cStringIO.StringIO()
- wb.save(stream)
- return stream.getvalue()
+ stream = cStringIO.StringIO()
+ wb.save(stream)
+ return stream.getvalue()
def export_book(databook):
- """Returns XLS representation of DataBook."""
+ """Returns XLS representation of DataBook."""
- wb = xlwt.Workbook(encoding='utf8')
+ 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 i, dset in enumerate(databook._datasets):
+ ws = wb.add_sheet(dset.title if dset.title else 'Sheet%s' % (i))
- dset_sheet(dset, ws)
+ dset_sheet(dset, ws)
- stream = cStringIO.StringIO()
- wb.save(stream)
- return stream.getvalue()
+ stream = cStringIO.StringIO()
+ wb.save(stream)
+ return stream.getvalue()
def dset_sheet(dataset, ws):
- """Completes given worksheet from given Dataset."""
- _package = dataset._package(dicts=False)
-
- for i, sep in enumerate(dataset._separators):
- _offset = i
- _package.insert((sep[0] + _offset), (sep[1],))
-
- for i, row in enumerate(_package):
- for j, col in enumerate(row):
-
- # bold headers
- if (i == 0) and dataset.headers:
- ws.write(i, j, col, bold)
-
- # frozen header row
- ws.panes_frozen = True
- ws.horz_split_pos = 1
-
-
- # bold separators
- elif len(row) < dataset.width:
- ws.write(i, j, col, bold)
-
- # wrap the rest
- else:
- try:
- if '\n' in col:
- ws.write(i, j, col, wrap)
- else:
- ws.write(i, j, col)
- except TypeError:
- ws.write(i, j, col)
+ """Completes given worksheet from given Dataset."""
+ _package = dataset._package(dicts=False)
+
+ for i, sep in enumerate(dataset._separators):
+ _offset = i
+ _package.insert((sep[0] + _offset), (sep[1],))
+
+ for i, row in enumerate(_package):
+ for j, col in enumerate(row):
+
+ # bold headers
+ if (i == 0) and dataset.headers:
+ ws.write(i, j, col, bold)
+
+ # frozen header row
+ ws.panes_frozen = True
+ ws.horz_split_pos = 1
+
+
+ # bold separators
+ elif len(row) < dataset.width:
+ ws.write(i, j, col, bold)
+
+ # wrap the rest
+ else:
+ try:
+ if '\n' in col:
+ ws.write(i, j, col, wrap)
+ else:
+ ws.write(i, j, col)
+ except TypeError:
+ ws.write(i, j, col)
diff --git a/tablib/formats/_yaml.py b/tablib/formats/_yaml.py
index 59d49a0..3f2f8b7 100644
--- a/tablib/formats/_yaml.py
+++ b/tablib/formats/_yaml.py
@@ -4,9 +4,9 @@
"""
try:
- import yaml
+ import yaml
except ImportError:
- import tablib.packages.yaml as yaml
+ import tablib.packages.yaml as yaml
import tablib
@@ -18,40 +18,40 @@ extentions = ('yaml', 'yml')
def export_set(dataset):
- """Returns YAML representation of Dataset."""
- return yaml.dump(dataset.dict)
+ """Returns YAML representation of Dataset."""
+ return yaml.dump(dataset.dict)
def export_book(databook):
- """Returns YAML representation of Databook."""
- return yaml.dump(databook._package())
+ """Returns YAML representation of Databook."""
+ return yaml.dump(databook._package())
def import_set(dset, in_stream):
- """Returns dataset from YAML stream."""
+ """Returns dataset from YAML stream."""
- dset.wipe()
- dset.dict = yaml.load(in_stream)
+ dset.wipe()
+ dset.dict = yaml.load(in_stream)
def import_book(dbook, in_stream):
- """Returns databook from YAML stream."""
+ """Returns databook from YAML stream."""
- dbook.wipe()
+ 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)
-
+ for sheet in yaml.load(in_stream):
+ data = tablib.core.Dataset()
+ data.title = sheet['title']
+ data.dict = sheet['data']
+ dbook.add_sheet(data)
+
def detect(stream):
- """Returns True if given stream is valid YAML."""
- try:
- _yaml = yaml.load(stream)
- if isinstance(_yaml, (list, tuple, dict)):
- return True
- else:
- return False
- except yaml.parser.ParserError:
- return False \ No newline at end of file
+ """Returns True if given stream is valid YAML."""
+ try:
+ _yaml = yaml.load(stream)
+ if isinstance(_yaml, (list, tuple, dict)):
+ return True
+ else:
+ return False
+ except yaml.parser.ParserError:
+ return False \ No newline at end of file
diff --git a/tablib/helpers.py b/tablib/helpers.py
index f75c466..718d159 100644
--- a/tablib/helpers.py
+++ b/tablib/helpers.py
@@ -7,31 +7,31 @@ import sys
class Struct(object):
- """Your attributes are belong to us."""
-
- def __init__(self, **entries):
- self.__dict__.update(entries)
-
- def __getitem__(self, key):
- return getattr(self, key, None)
+ """Your attributes are belong to us."""
+
+ def __init__(self, **entries):
+ self.__dict__.update(entries)
+
+ def __getitem__(self, key):
+ return getattr(self, key, None)
- def dictionary(self):
- """Returns dictionary representation of object."""
- return self.__dict__
+ def dictionary(self):
+ """Returns dictionary representation of object."""
+ return self.__dict__
- def items(self):
- """Returns items within object."""
- return self.__dict__.items()
+ def items(self):
+ """Returns items within object."""
+ return self.__dict__.items()
- def keys(self):
- """Returns keys within object."""
- return self.__dict__.keys()
+ def keys(self):
+ """Returns keys within object."""
+ return self.__dict__.keys()
def piped():
- """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
+ """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
diff --git a/tablib/packages/markup.py b/tablib/packages/markup.py
index 98d9b1d..72a7162 100644
--- a/tablib/packages/markup.py
+++ b/tablib/packages/markup.py
@@ -29,10 +29,10 @@ class element:
def __init__( self, tag, case='lower', parent=None ):
self.parent = parent
- if case == 'lower':
- self.tag = tag.lower( )
- else:
- self.tag = tag.upper( )
+ if case == 'lower':
+ self.tag = tag.lower( )
+ else:
+ self.tag = tag.upper( )
def __call__( self, *args, **kwargs ):
if len( args ) > 1:
@@ -67,8 +67,8 @@ class element:
def render( self, tag, single, between, kwargs ):
"""Append the actual tags to content."""
- out = "<%s" % tag
- for key, value in kwargs.iteritems( ):
+ out = "<%s" % tag
+ for key, value in kwargs.iteritems( ):
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?
@@ -78,13 +78,13 @@ class element:
out = "%s %s=\"%s\"" % ( out, key, escape( value ) )
else:
out = "%s %s" % ( out, key )
- if between is not None:
- out = "%s>%s</%s>" % ( out, between, tag )
- else:
- if single:
- out = "%s />" % out
- else:
- out = "%s>" % out
+ if between is not None:
+ out = "%s>%s</%s>" % ( out, between, tag )
+ else:
+ if single:
+ out = "%s />" % out
+ else:
+ out = "%s>" % out
if self.parent is not None:
self.parent.content.append( out )
else:
@@ -145,30 +145,30 @@ class page:
deprecated_twotags = [ "APPLET", "CENTER", "DIR", "FONT", "MENU", "S", "STRIKE", "U" ]
self.header = [ ]
- self.content = [ ]
+ self.content = [ ]
self.footer = [ ]
- self.case = case
+ self.case = case
self.separator = separator
# init( ) sets it to True so we know that </body></html> has to be printed at the end
self._full = False
self.class_= class_
- if mode == 'strict_html' or mode == 'html':
- self.onetags = valid_onetags
- self.onetags += map( string.lower, self.onetags )
- self.twotags = valid_twotags
- self.twotags += map( string.lower, self.twotags )
- self.deptags = deprecated_onetags + deprecated_twotags
- self.deptags += 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.twotags = valid_twotags + deprecated_twotags
- self.twotags += map( string.lower, self.twotags )
- self.mode = mode
- elif mode == 'xml':
+ if mode == 'strict_html' or mode == 'html':
+ self.onetags = valid_onetags
+ self.onetags += map( string.lower, self.onetags )
+ self.twotags = valid_twotags
+ self.twotags += map( string.lower, self.twotags )
+ self.deptags = deprecated_onetags + deprecated_twotags
+ self.deptags += 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.twotags = valid_twotags + deprecated_twotags
+ self.twotags += map( string.lower, self.twotags )
+ self.mode = mode
+ elif mode == 'xml':
if onetags and twotags:
self.onetags = onetags
self.twotags = twotags
@@ -178,8 +178,8 @@ class page:
self.onetags = russell( )
self.twotags = russell( )
self.mode = mode
- else:
- raise ModeError( mode )
+ else:
+ raise ModeError( mode )
def __getattr__( self, attr ):
if attr.startswith("__") and attr.endswith("__"):
@@ -192,7 +192,7 @@ class page:
end = [ '</body>', '</html>' ]
else:
end = [ ]
-
+
return self.separator.join( self.header + self.content + self.footer + end )
def __call__( self, escape=False ):
@@ -444,37 +444,37 @@ class russell:
"""A dummy class that contains anything."""
def __contains__( self, item ):
- return True
+ return True
class MarkupError( Exception ):
"""All our exceptions subclass this."""
def __str__( self ):
- return self.message
+ return self.message
class ClosingError( MarkupError ):
def __init__( self, tag ):
- self.message = "The element '%s' does not accept non-keyword arguments (has no closing tag)." % tag
+ self.message = "The element '%s' does not accept non-keyword arguments (has no closing tag)." % tag
class OpeningError( MarkupError ):
def __init__( self, tag ):
- self.message = "The element '%s' can not be opened." % tag
+ self.message = "The element '%s' can not be opened." % tag
class ArgumentError( MarkupError ):
def __init__( self, tag ):
- self.message = "The element '%s' was called with more than one non-keyword argument." % tag
+ self.message = "The element '%s' was called with more than one non-keyword argument." % tag
class InvalidElementError( MarkupError ):
def __init__( self, tag, mode ):
- self.message = "The element '%s' is not valid for your mode '%s'." % ( tag, mode )
+ self.message = "The element '%s' is not valid for your mode '%s'." % ( tag, mode )
class DeprecationError( MarkupError ):
def __init__( self, tag ):
- self.message = "The element '%s' is deprecated, instantiate markup.page with mode='loose_html' to allow it." % tag
+ self.message = "The element '%s' is deprecated, instantiate markup.page with mode='loose_html' to allow it." % tag
class ModeError( MarkupError ):
def __init__( self, mode ):
- self.message = "Mode '%s' is invalid, possible values: strict_html, loose_html, xml." % mode
+ self.message = "Mode '%s' is invalid, possible values: strict_html, loose_html, xml." % mode
class CustomizationError( MarkupError ):
def __init__( self ):
diff --git a/test_tablib.py b/test_tablib.py
index 15630f2..e4a4d11 100755
--- a/test_tablib.py
+++ b/test_tablib.py
@@ -12,452 +12,452 @@ import tablib
class TablibTestCase(unittest.TestCase):
- """Tablib test cases."""
+ """Tablib test cases."""
- def setUp(self):
- """Create simple data set with headers."""
+ def setUp(self):
+ """Create simple data set with headers."""
- global data, book
+ global data, book
- data = tablib.Dataset()
- book = tablib.Databook()
+ 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.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)
+ 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 tearDown(self):
+ """Teardown."""
+ pass
- def test_empty_append(self):
- """Verify append() correctly adds tuple with no headers."""
- new_row = (1, 2, 3)
- data.append(new_row)
+ def test_empty_append(self):
+ """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)
+ # 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)
+ 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)
- 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."""
+ def test_add_column(self):
+ """Verify adding column works with/without headers."""
- data.append(['kenneth'])
- data.append(['bessie'])
+ data.append(['kenneth'])
+ data.append(['bessie'])
- new_col = ['reitz', 'monke']
+ new_col = ['reitz', 'monke']
- data.append(col=new_col)
+ data.append(col=new_col)
- self.assertEquals(data[0], ('kenneth', 'reitz'))
- self.assertEquals(data.width, 2)
+ self.assertEquals(data[0], ('kenneth', 'reitz'))
+ self.assertEquals(data.width, 2)
- # With Headers
- data.headers = ('fname', 'lname')
- new_col = [21, 22]
- data.append(col=new_col, header='age')
+ # With Headers
+ data.headers = ('fname', 'lname')
+ new_col = [21, 22]
+ data.append(col=new_col, header='age')
- self.assertEquals(data['age'], new_col)
+ self.assertEquals(data['age'], new_col)
- def test_add_column_no_data_no_headers(self):
- """Verify adding new column with no headers."""
+ def test_add_column_no_data_no_headers(self):
+ """Verify adding new column with no headers."""
- new_col = ('reitz', 'monke')
+ new_col = ('reitz', 'monke')
- data.append(col=new_col)
+ 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))
+ self.assertEquals(data[0], tuple([new_col[0]]))
+ self.assertEquals(data.width, 1)
+ self.assertEquals(data.height, len(new_col))
- def test_add_callable_column(self):
- """Verify adding column with values specified as callable."""
- new_col = [lambda x: x[0]]
- self.founders.append(col=new_col, header='first_again')
+ def test_add_callable_column(self):
+ """Verify adding column with values specified as callable."""
+ new_col = [lambda x: x[0]]
+ self.founders.append(col=new_col, header='first_again')
#
-# self.assertTrue(map(lambda x: x[0] == x[-1], self.founders))
+# self.assertTrue(map(lambda x: x[0] == x[-1], self.founders))
- def test_header_slicing(self):
- """Verify slicing by headers."""
+ 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]])
+ 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."""
+ 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 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])
+ # 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."""
+ 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])
+ # 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)
+ # 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])
+ # 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)
+ # 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)
+ # Delete from invalid index
+ self.assertRaises(IndexError, self.founders.__delitem__, 3)
- def test_csv_export(self):
- """Verify exporting dataset object as CSV."""
+ 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 + ','
+ # 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'
+ csv = csv.strip(',') + '\r\n'
- for founder in self.founders:
- for col in founder:
- csv += str(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)
+ self.assertEqual(csv, self.founders.csv)
- def test_tsv_export(self):
- """Verify exporting dataset object as CSV."""
+ def test_tsv_export(self):
+ """Verify exporting dataset object as CSV."""
- # Build up the csv string with headers first, followed by each row
- tsv = ''
- for col in self.headers:
- tsv += col + '\t'
+ # Build up the csv string with headers first, followed by each row
+ tsv = ''
+ for col in self.headers:
+ tsv += col + '\t'
- tsv = tsv.strip('\t') + '\r\n'
+ tsv = tsv.strip('\t') + '\r\n'
- for founder in self.founders:
- for col in founder:
- tsv += str(col) + '\t'
- tsv = tsv.strip('\t') + '\r\n'
+ for founder in self.founders:
+ for col in founder:
+ tsv += str(col) + '\t'
+ tsv = tsv.strip('\t') + '\r\n'
- self.assertEqual(tsv, self.founders.tsv)
+ self.assertEqual(tsv, self.founders.tsv)
- def test_html_export(self):
+ def test_html_export(self):
- """HTML export"""
+ """HTML export"""
- html = markup.page()
- html.table.open()
- html.thead.open()
+ html = markup.page()
+ html.table.open()
+ html.thead.open()
- html.tr(markup.oneliner.th(self.founders.headers))
- html.thead.close()
+ html.tr(markup.oneliner.th(self.founders.headers))
+ html.thead.close()
- for founder in self.founders:
+ for founder in self.founders:
- html.tr(markup.oneliner.td(founder))
+ html.tr(markup.oneliner.td(founder))
- html.table.close()
- html = str(html)
+ html.table.close()
+ html = str(html)
- self.assertEqual(html, self.founders.html)
+ self.assertEqual(html, self.founders.html)
- def test_unicode_append(self):
- """Passes in a single unicode charecter and exports."""
+ def test_unicode_append(self):
+ """Passes in a single unicode charecter and exports."""
- new_row = ('å', 'é')
- data.append(new_row)
+ new_row = ('å', 'é')
+ data.append(new_row)
- data.json
- data.yaml
- data.csv
- data.tsv
- data.xls
+ data.json
+ data.yaml
+ data.csv
+ data.tsv
+ data.xls
- def test_book_export_no_exceptions(self):
- """Test that varoius exports don't error out."""
+ def test_book_export_no_exceptions(self):
+ """Test that varoius exports don't error out."""
- book = tablib.Databook()
- book.add_sheet(data)
+ book = tablib.Databook()
+ book.add_sheet(data)
- book.json
- book.yaml
- book.xls
+ 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
+ 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
+ _json = data.json
- data.json = _json
+ data.json = _json
- self.assertEqual(_json, data.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
+ 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.add_sheet(data)
+ _json = book.json
- book.json = _json
+ book.json = _json
- self.assertEqual(_json, book.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
+ 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
+ _yaml = data.yaml
- data.yaml = _yaml
+ data.yaml = _yaml
- self.assertEqual(_yaml, data.yaml)
+ self.assertEqual(_yaml, data.yaml)
- def test_yaml_import_book(self):
- """Generate and import YAML book serialization."""
- data.append(self.john)
- data.append(self.george)
- data.headers = self.headers
+ 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.add_sheet(data)
+ _yaml = book.yaml
- book.yaml = _yaml
+ book.yaml = _yaml
- self.assertEqual(_yaml, book.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
+ 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
+ _csv = data.csv
- data.csv = _csv
+ data.csv = _csv
- self.assertEqual(_csv, data.csv)
+ self.assertEqual(_csv, data.csv)
- def test_tsv_import_set(self):
- """Generate and import TSV set serialization."""
- data.append(self.john)
- data.append(self.george)
- data.headers = self.headers
+ def test_tsv_import_set(self):
+ """Generate and import TSV set serialization."""
+ data.append(self.john)
+ data.append(self.george)
+ data.headers = self.headers
- _tsv = data.tsv
+ _tsv = data.tsv
- data.tsv = _tsv
+ data.tsv = _tsv
- self.assertEqual(_tsv, data.tsv)
+ self.assertEqual(_tsv, data.tsv)
- def test_csv_format_detect(self):
- """Test CSV format detection."""
+ def test_csv_format_detect(self):
+ """Test CSV format detection."""
- _csv = (
- '1,2,3\n'
- '4,5,6\n'
- '7,8,9\n'
- )
- _bunk = (
- '¡¡¡¡¡¡¡¡£™∞¢£§∞§¶•¶ª∞¶•ªº••ª–º§•†•§º¶•†¥ª–º•§ƒø¥¨©πƒø†ˆ¥ç©¨√øˆ¥≈†ƒ¥ç©ø¨çˆ¥ƒçø¶'
- )
+ _csv = (
+ '1,2,3\n'
+ '4,5,6\n'
+ '7,8,9\n'
+ )
+ _bunk = (
+ '¡¡¡¡¡¡¡¡£™∞¢£§∞§¶•¶ª∞¶•ªº••ª–º§•†•§º¶•†¥ª–º•§ƒø¥¨©πƒø†ˆ¥ç©¨√øˆ¥≈†ƒ¥ç©ø¨çˆ¥ƒçø¶'
+ )
- self.assertTrue(tablib.formats.csv.detect(_csv))
- self.assertFalse(tablib.formats.csv.detect(_bunk))
+ self.assertTrue(tablib.formats.csv.detect(_csv))
+ self.assertFalse(tablib.formats.csv.detect(_bunk))
- def test_tsv_format_detect(self):
- """Test TSV format detection."""
+ def test_tsv_format_detect(self):
+ """Test TSV format detection."""
- _tsv = (
- '1\t2\t3\n'
- '4\t5\t6\n'
- '7\t8\t9\n'
- )
- _bunk = (
- '¡¡¡¡¡¡¡¡£™∞¢£§∞§¶•¶ª∞¶•ªº••ª–º§•†•§º¶•†¥ª–º•§ƒø¥¨©πƒø†ˆ¥ç©¨√øˆ¥≈†ƒ¥ç©ø¨çˆ¥ƒçø¶'
- )
+ _tsv = (
+ '1\t2\t3\n'
+ '4\t5\t6\n'
+ '7\t8\t9\n'
+ )
+ _bunk = (
+ '¡¡¡¡¡¡¡¡£™∞¢£§∞§¶•¶ª∞¶•ªº••ª–º§•†•§º¶•†¥ª–º•§ƒø¥¨©πƒø†ˆ¥ç©¨√øˆ¥≈†ƒ¥ç©ø¨çˆ¥ƒçø¶'
+ )
- self.assertTrue(tablib.formats.tsv.detect(_tsv))
- self.assertFalse(tablib.formats.tsv.detect(_bunk))
+ self.assertTrue(tablib.formats.tsv.detect(_tsv))
+ self.assertFalse(tablib.formats.tsv.detect(_bunk))
- def test_json_format_detect(self):
- """Test JSON format detection."""
+ def test_json_format_detect(self):
+ """Test JSON format detection."""
- _json = '[{"last_name": "Adams","age": 90,"first_name": "John"}]'
- _bunk = (
- '¡¡¡¡¡¡¡¡£™∞¢£§∞§¶•¶ª∞¶•ªº••ª–º§•†•§º¶•†¥ª–º•§ƒø¥¨©πƒø†ˆ¥ç©¨√øˆ¥≈†ƒ¥ç©ø¨çˆ¥ƒçø¶'
- )
+ _json = '[{"last_name": "Adams","age": 90,"first_name": "John"}]'
+ _bunk = (
+ '¡¡¡¡¡¡¡¡£™∞¢£§∞§¶•¶ª∞¶•ªº••ª–º§•†•§º¶•†¥ª–º•§ƒø¥¨©πƒø†ˆ¥ç©¨√øˆ¥≈†ƒ¥ç©ø¨çˆ¥ƒçø¶'
+ )
- self.assertTrue(tablib.formats.json.detect(_json))
- self.assertFalse(tablib.formats.json.detect(_bunk))
+ self.assertTrue(tablib.formats.json.detect(_json))
+ self.assertFalse(tablib.formats.json.detect(_bunk))
- def test_yaml_format_detect(self):
- """Test YAML format detection."""
+ def test_yaml_format_detect(self):
+ """Test YAML format detection."""
- _yaml = '- {age: 90, first_name: John, last_name: Adams}'
- _bunk = (
- '¡¡¡¡¡¡---///\n\n\n¡¡£™∞¢£§∞§¶•¶ª∞¶•ªº••ª–º§•†•§º¶•†¥ª–º•§ƒø¥¨©πƒø†ˆ¥ç©¨√øˆ¥≈†ƒ¥ç©ø¨çˆ¥ƒçø¶'
- )
+ _yaml = '- {age: 90, first_name: John, last_name: Adams}'
+ _bunk = (
+ '¡¡¡¡¡¡---///\n\n\n¡¡£™∞¢£§∞§¶•¶ª∞¶•ªº••ª–º§•†•§º¶•†¥ª–º•§ƒø¥¨©πƒø†ˆ¥ç©¨√øˆ¥≈†ƒ¥ç©ø¨çˆ¥ƒçø¶'
+ )
- self.assertTrue(tablib.formats.yaml.detect(_yaml))
- self.assertFalse(tablib.formats.yaml.detect(_bunk))
+ self.assertTrue(tablib.formats.yaml.detect(_yaml))
+ self.assertFalse(tablib.formats.yaml.detect(_bunk))
- def test_auto_format_detect(self):
- """Test auto format detection."""
+ def test_auto_format_detect(self):
+ """Test auto format detection."""
- _yaml = '- {age: 90, first_name: John, last_name: Adams}'
- _json = '[{"last_name": "Adams","age": 90,"first_name": "John"}]'
- _csv = '1,2,3\n4,5,6\n7,8,9\n'
- _bunk = '¡¡¡¡¡¡---///\n\n\n¡¡£™∞¢£§∞§¶•¶ª∞¶•ªº••ª–º§•†•§º¶•†¥ª–º•§ƒø¥¨©πƒø†ˆ¥ç©¨√øˆ¥≈†ƒ¥ç©ø¨çˆ¥ƒçø¶'
+ _yaml = '- {age: 90, first_name: John, last_name: Adams}'
+ _json = '[{"last_name": "Adams","age": 90,"first_name": "John"}]'
+ _csv = '1,2,3\n4,5,6\n7,8,9\n'
+ _bunk = '¡¡¡¡¡¡---///\n\n\n¡¡£™∞¢£§∞§¶•¶ª∞¶•ªº••ª–º§•†•§º¶•†¥ª–º•§ƒø¥¨©πƒø†ˆ¥ç©¨√øˆ¥≈†ƒ¥ç©ø¨çˆ¥ƒçø¶'
- self.assertEqual(tablib.detect(_yaml)[0], tablib.formats.yaml)
- self.assertEqual(tablib.detect(_csv)[0], tablib.formats.csv)
- self.assertEqual(tablib.detect(_json)[0], tablib.formats.json)
- self.assertEqual(tablib.detect(_bunk)[0], None)
+ self.assertEqual(tablib.detect(_yaml)[0], tablib.formats.yaml)
+ self.assertEqual(tablib.detect(_csv)[0], tablib.formats.csv)
+ self.assertEqual(tablib.detect(_json)[0], tablib.formats.json)
+ self.assertEqual(tablib.detect(_bunk)[0], None)
- def test_transpose(self):
- """Transpose a dataset."""
+ def test_transpose(self):
+ """Transpose a dataset."""
- transposed_founders = self.founders.transpose()
- first_row = transposed_founders[0]
- second_row = transposed_founders[1]
+ transposed_founders = self.founders.transpose()
+ first_row = transposed_founders[0]
+ second_row = transposed_founders[1]
- self.assertEqual(transposed_founders.headers,
- ["first_name","John", "George", "Thomas"])
- self.assertEqual(first_row,
- ("last_name","Adams", "Washington", "Jefferson"))
- self.assertEqual(second_row,
- ("gpa",90, 67, 50))
+ self.assertEqual(transposed_founders.headers,
+ ["first_name","John", "George", "Thomas"])
+ self.assertEqual(first_row,
+ ("last_name","Adams", "Washington", "Jefferson"))
+ self.assertEqual(second_row,
+ ("gpa",90, 67, 50))
- def test_row_stacking(self):
+ def test_row_stacking(self):
- """Row stacking."""
+ """Row stacking."""
- to_join = tablib.Dataset(headers=self.founders.headers)
+ to_join = tablib.Dataset(headers=self.founders.headers)
- for row in self.founders:
- to_join.append(row=row)
+ for row in self.founders:
+ to_join.append(row=row)
- row_stacked = self.founders.stack_rows(to_join)
+ row_stacked = self.founders.stack_rows(to_join)
- for column in row_stacked.headers:
+ for column in row_stacked.headers:
- original_data = self.founders[column]
- expected_data = original_data + original_data
- self.assertEqual(row_stacked[column], expected_data)
+ original_data = self.founders[column]
+ expected_data = original_data + original_data
+ self.assertEqual(row_stacked[column], expected_data)
- def test_column_stacking(self):
+ def test_column_stacking(self):
- """Column stacking"""
+ """Column stacking"""
- to_join = tablib.Dataset(headers=self.founders.headers)
+ to_join = tablib.Dataset(headers=self.founders.headers)
- for row in self.founders:
- to_join.append(row=row)
+ for row in self.founders:
+ to_join.append(row=row)
- column_stacked = self.founders.stack_columns(to_join)
+ column_stacked = self.founders.stack_columns(to_join)
- for index, row in enumerate(column_stacked):
+ for index, row in enumerate(column_stacked):
- original_data = self.founders[index]
- expected_data = original_data + original_data
- self.assertEqual(row, expected_data)
+ original_data = self.founders[index]
+ expected_data = original_data + original_data
+ self.assertEqual(row, expected_data)
- self.assertEqual(column_stacked[0],
- ("John", "Adams", 90, "John", "Adams", 90))
+ self.assertEqual(column_stacked[0],
+ ("John", "Adams", 90, "John", "Adams", 90))
- def test_sorting(self):
+ def test_sorting(self):
- """Sort columns."""
+ """Sort columns."""
- sorted_data = self.founders.sort(col="first_name")
+ sorted_data = self.founders.sort(col="first_name")
- first_row = sorted_data[0]
- second_row = sorted_data[2]
- third_row = sorted_data[1]
- expected_first = self.founders[1]
- expected_second = self.founders[2]
- expected_third = self.founders[0]
+ first_row = sorted_data[0]
+ second_row = sorted_data[2]
+ third_row = sorted_data[1]
+ expected_first = self.founders[1]
+ expected_second = self.founders[2]
+ expected_third = self.founders[0]
- self.assertEqual(first_row, expected_first)
- self.assertEqual(second_row, expected_second)
- self.assertEqual(third_row, expected_third)
+ self.assertEqual(first_row, expected_first)
+ self.assertEqual(second_row, expected_second)
+ self.assertEqual(third_row, expected_third)
- def test_wipe(self):
- """Purge a dataset."""
+ def test_wipe(self):
+ """Purge a dataset."""
- new_row = (1, 2, 3)
- data.append(new_row)
+ 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)
+ # 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)
+ 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__':
- unittest.main()
+ unittest.main()