clean code

This commit is contained in:
chfw 2016-06-08 23:03:04 +01:00
parent 3d4aebe539
commit c6674f51be
16 changed files with 126 additions and 323 deletions

View File

@ -30,11 +30,11 @@ before_install:
- if [[ -f min_requirements.txt && "$MINREQ" -eq 1 ]]; then
mv min_requirements.txt requirements.txt ;
fi
- test ! -f rnd_requirements.txt || pip install --upgrade "setuptools" "pip==7.1"
- pip install --upgrade "setuptools" "pip==7.1"
- test ! -f rnd_requirements.txt || pip install --no-deps -r rnd_requirements.txt
- test ! -f rnd_requirements.txt || pip install -r rnd_requirements.txt ;
- pip install -r tests/requirements.txt
script:
make test
- make test
after_success:
codecov

View File

@ -18,6 +18,13 @@ Fonts, colors and charts are not supported.
Installation
================================================================================
Recently, pyexcel(0.2.2+) and its plugins(0.2.0+) started using newer version of setuptools. Please upgrade your setup tools before install latest pyexcel components:
.. code-block:: bash
$ pip install --upgrade setuptools
You can install it via pip:
.. code-block:: bash

View File

@ -1,20 +1,4 @@
# -*- coding: utf-8 -*-
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
@ -22,230 +6,34 @@ extensions = [
'sphinx.ext.viewcode',
]
intersphinx_mapping = {'pyexcel': ('http://pyexcel.readthedocs.org/en/latest/', None)}
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'pyexcel-xls'
copyright = u'2015-2016 Onni Software Ltd.'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.2.0'
# The full version, including alpha/beta/rc tags.
release = '0.2.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'pyexcel-xlsdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
intersphinx_mapping = {
'pyexcel': ('http://pyexcel.readthedocs.org/en/latest/', None)
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
project = u'pyexcel-xls'
copyright = u'2015-2016 Onni Software Ltd.'
version = '0.2.0'
release = '0.2.0'
exclude_patterns = []
pygments_style = 'sphinx'
html_theme = 'default'
html_static_path = ['_static']
htmlhelp_basename = 'pyexcel-xlsdoc'
latex_elements = {}
latex_documents = [
('index', 'pyexcel-xls.tex', u'pyexcel-xls Documentation',
u'Onni Software Ltd.', 'manual'),
('index', 'pyexcel-xls.tex', u'pyexcel-xls Documentation',
'Onni Software Ltd.', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'pyexcel-xls', u'pyexcel-xls Documentation',
[u'Onni Software Ltd.'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'pyexcel-xls', u'pyexcel-xls Documentation',
u'Onni Software Ltd.', 'pyexcel-xls', 'One line description of project.',
'Miscellaneous'),
('index', 'pyexcel-xls', u'pyexcel-xls Documentation',
'Onni Software Ltd.', 'pyexcel-xls', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False

View File

@ -7,6 +7,7 @@
:copyright: (c) 2015-2016 by Onni Software Ltd
:license: New BSD License
"""
# flake8: noqa
# this line has to be place above all else
# because of dynamic import
_FILE_TYPE = 'xls'
@ -28,5 +29,3 @@ def save_data(afile, data, file_type=None, **keywords):
if isstream(afile) and file_type is None:
file_type = _FILE_TYPE
write_data(afile, data, file_type=file_type, **keywords)

View File

@ -126,7 +126,7 @@ class XLSBook(BookReader):
def open(self, file_name, **keywords):
BookReader.open(self, file_name, **keywords)
self._get_params()
def open_stream(self, file_stream, **keywords):
BookReader.open_stream(self, file_stream, **keywords)
self._get_params()
@ -264,12 +264,15 @@ _xls_reader_registry = {
"library": "pyexcel-xls"
}
_XLSM_MIME = (
"application/" +
"vnd.openxmlformats-officedocument.spreadsheetml.sheet")
_xlsm_registry = {
"file_type": "xlsm",
"reader": XLSBook,
"stream_type": "binary",
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"mime_type": _XLSM_MIME,
"library": "pyexcel-xls"
}

View File

@ -11,11 +11,15 @@ VERSION = '0.2.0'
EMAIL = 'wangc_2011 (at) hotmail.com'
LICENSE = 'New BSD'
PACKAGES = find_packages(exclude=['ez_setup', 'examples', 'tests'])
DESCRIPTION = 'A wrapper library to read, manipulate and write data in xls format. It reads xlsx and xlsm format'
DESCRIPTION = (
'A wrapper library to read, manipulate and write data in xls format. It' +
' reads xlsx and xlsm format' +
''
)
KEYWORDS = [
'excel',
'python',
'pyexcel',
'excel',
'python',
'pyexcel',
'xls',
'xlsx',
'xlsm'
@ -27,12 +31,12 @@ INSTALL_REQUIRES = [
]
EXTRAS_REQUIRE = {
':python_version<"3"': [
'xlwt'
],
':python_version>="3"': [
'xlwt-future'
],
':python_version<"3"': [
'xlwt'
],
':python_version>="3"': [
'xlwt-future'
],
}
CLASSIFIERS = [

View File

@ -1,2 +1,2 @@
pip freeze
nosetests --with-cov --cover-package pyexcel_xls --cover-package tests --with-doctest --doctest-extension=.rst tests README.rst pyexcel_xls
nosetests --with-cov --cover-package pyexcel_xls --cover-package tests --with-doctest --doctest-extension=.rst tests README.rst pyexcel_xls && flake8 . --exclude=.moban.d

View File

@ -1,2 +1,2 @@
pip freeze
nosetests --with-cov --cover-package pyexcel_xls --cover-package tests --with-doctest --doctest-extension=.rst tests README.rst pyexcel_xls
nosetests --with-cov --cover-package pyexcel_xls --cover-package tests --with-doctest --doctest-extension=.rst tests README.rst pyexcel_xls && flake8 . --exclude=.moban.d

View File

@ -1,3 +1,4 @@
# flake8: noqa
import sys

View File

@ -3,7 +3,7 @@ import pyexcel
def create_sample_file1(file):
data=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 1.1, 1]
data = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 1.1, 1]
table = []
table.append(data[:4])
table.append(data[4:8])
@ -16,17 +16,17 @@ class PyexcelHatWriterBase:
Abstract functional test for hat writers
"""
content = {
"X": [1,2,3,4,5],
"Y": [6,7,8,9,10],
"Z": [11,12,13,14,15],
"X": [1, 2, 3, 4, 5],
"Y": [6, 7, 8, 9, 10],
"Z": [11, 12, 13, 14, 15]
}
def test_series_table(self):
pyexcel.save_as(adict=self.content, dest_file_name=self.testfile)
r = pyexcel.SeriesReader(self.testfile)
actual = pyexcel.utils.to_dict(r)
assert actual == self.content
class PyexcelWriterBase:
"""
@ -36,15 +36,15 @@ class PyexcelWriterBase:
it is used for testing
"""
content = [
[1,2,3,4,5],
[1,2,3,4,5],
[1,2,3,4,5],
[1,2,3,4,5]
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5]
]
def _create_a_file(self, file):
pyexcel.save_as(dest_file_name=file, array=self.content)
def test_write_array(self):
self._create_a_file(self.testfile)
r = pyexcel.Reader(self.testfile)
@ -79,8 +79,8 @@ class PyexcelMultipleSheetBase:
os.unlink(self.testfile)
def test_sheet_names(self):
r = pyexcel.BookReader( self.testfile)
expected = [ "Sheet1", "Sheet2", "Sheet3"]
r = pyexcel.BookReader(self.testfile)
expected = ["Sheet1", "Sheet2", "Sheet3"]
sheet_names = r.sheet_names()
for name in sheet_names:
assert name in expected
@ -114,9 +114,9 @@ class PyexcelMultipleSheetBase:
def test_random_access_operator(self):
r = pyexcel.BookReader(self.testfile)
value = r["Sheet1"][0,1]
value = r["Sheet1"][0, 1]
assert value == 1
value = r["Sheet3"][0,1]
value = r["Sheet3"][0, 1]
assert value == 'Y'
r["Sheet3"].name_columns_by_row(0)
assert r["Sheet3"][0,1] == 4
assert r["Sheet3"][0, 1] == 4

View File

@ -1,4 +1,5 @@
nose
codecov
coverage
flake8
pyexcel

View File

@ -20,7 +20,7 @@ class TestBugFix:
s = pe.load(os.path.join("tests",
"test-fixtures",
"test-date-format.xls"))
assert s[0,0] == datetime.datetime(2015, 11, 11, 11, 12, 0)
assert s[0, 0] == datetime.datetime(2015, 11, 11, 11, 12, 0)
def test_pyexcel_xls_issue_2(self):
data = OrderedDict()
@ -28,5 +28,5 @@ class TestBugFix:
for i in range(4100):
array.append([datetime.datetime.now()])
data.update({"test": array})
s = save_data("test.xls", data)
save_data("test.xls", data)
os.unlink("test.xls")

View File

@ -13,35 +13,35 @@ class TestDateFormat:
25/12/14 11:11:11
25/12/14 12:11:11
01/01/15 13:13:13
0.0 0.0
0.0 0.0
"""
r = pe.Reader(os.path.join("tests", "fixtures", "date_field.xls"))
assert isinstance(r[1,0], datetime.date) == True
assert r[1,0].strftime("%d/%m/%y") == "25/12/14"
assert isinstance(r[1,1], datetime.time) == True
assert r[1,1].strftime("%H:%M:%S") == "11:11:11"
assert r[4,0].strftime("%d/%m/%Y") == "01/01/1900"
assert r[4,1].strftime("%H:%M:%S") == "00:00:00"
assert isinstance(r[1, 0], datetime.date) is True
assert r[1, 0].strftime("%d/%m/%y") == "25/12/14"
assert isinstance(r[1, 1], datetime.time) is True
assert r[1, 1].strftime("%H:%M:%S") == "11:11:11"
assert r[4, 0].strftime("%d/%m/%Y") == "01/01/1900"
assert r[4, 1].strftime("%H:%M:%S") == "00:00:00"
def test_writing_date_format(self):
excel_filename = "testdateformat.xls"
data = [[datetime.date(2014,12,25),
datetime.time(11,11,11),
datetime.datetime(2014,12,25,11,11,11)]]
data = [[datetime.date(2014, 12, 25),
datetime.time(11, 11, 11),
datetime.datetime(2014, 12, 25, 11, 11, 11)]]
pe.save_as(dest_file_name=excel_filename, array=data)
r = pe.Reader(excel_filename)
assert isinstance(r[0,0], datetime.date) == True
assert r[0,0].strftime("%d/%m/%y") == "25/12/14"
assert isinstance(r[0,1], datetime.time) == True
assert r[0,1].strftime("%H:%M:%S") == "11:11:11"
assert isinstance(r[0,2], datetime.date) == True
assert r[0,2].strftime("%d/%m/%y %H:%M:%S") == "25/12/14 11:11:11"
assert isinstance(r[0, 0], datetime.date) is True
assert r[0, 0].strftime("%d/%m/%y") == "25/12/14"
assert isinstance(r[0, 1], datetime.time) is True
assert r[0, 1].strftime("%H:%M:%S") == "11:11:11"
assert isinstance(r[0, 2], datetime.date) is True
assert r[0, 2].strftime("%d/%m/%y %H:%M:%S") == "25/12/14 11:11:11"
os.unlink(excel_filename)
class TestAutoDetectInt(TestCase):
def setUp(self):
self.content = [[1,2,3.1]]
self.content = [[1, 2, 3.1]]
self.test_file = "test_auto_detect_init.xls"
pe.save_as(array=self.content, dest_file_name=self.test_file)

View File

@ -14,11 +14,7 @@ class TestXlsNxlsMultipleSheets(PyexcelMultipleSheetBase):
def setUp(self):
self.testfile = "multiple1.xls"
self.testfile2 = "multiple1.xls"
self.content = {
"Sheet1": [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]],
"Sheet2": [[4, 4, 4, 4], [5, 5, 5, 5], [6, 6, 6, 6]],
"Sheet3": [[u'X', u'Y', u'Z'], [1, 4, 7], [2, 5, 8], [3, 6, 9]]
}
self.content = _produce_ordered_dict()
self._write_test_file(self.testfile)
def tearDown(self):
@ -35,16 +31,14 @@ class TestAddBooks:
3,3,3,3
"""
self.rows = 3
pyexcel.save_book_as(bookdict=self.content,dest_file_name=file)
pyexcel.save_book_as(bookdict=self.content,
dest_file_name=file)
def setUp(self):
self.testfile = "multiple1.xls"
self.testfile2 = "multiple2.xls"
self.testfile3 = "multiple3.xls"
self.content = OrderedDict()
self.content.update({"Sheet1": [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]]})
self.content.update({"Sheet2": [[4, 4, 4, 4], [5, 5, 5, 5], [6, 6, 6, 6]]})
self.content.update({"Sheet3": [[u'X', u'Y', u'Z'], [1, 4, 7], [2, 5, 8], [3, 6, 9]]})
self.content = _produce_ordered_dict()
self._write_test_file(self.testfile)
self._write_test_file(self.testfile2)
@ -53,7 +47,6 @@ class TestAddBooks:
assert len(b1.sheet_names()) == 1
assert b1['Sheet1'].to_array() == self.content['Sheet1']
def test_load_a_single_sheet2(self):
b1 = pyexcel.load_book(self.testfile, sheet_index=0)
assert len(b1.sheet_names()) == 1
@ -62,7 +55,7 @@ class TestAddBooks:
@raises(IndexError)
def test_load_a_single_sheet3(self):
pyexcel.get_book(file_name=self.testfile, sheet_index=10000)
@raises(ValueError)
def test_load_a_single_sheet4(self):
pyexcel.get_book(file_name=self.testfile, sheet_name="Not exist")
@ -74,17 +67,17 @@ class TestAddBooks:
assert len(b1.sheet_names()) == 2
try:
del b1["Sheet1"]
assert 1==2
assert 1 == 2
except KeyError:
assert 1==1
assert 1 == 1
del b1[1]
assert len(b1.sheet_names()) == 1
try:
del b1[1]
assert 1==2
assert 1 == 2
except IndexError:
assert 1==1
assert 1 == 1
def test_delete_sheets2(self):
"""repetitively delete first sheet"""
b1 = pyexcel.load_book(self.testfile)
@ -94,7 +87,7 @@ class TestAddBooks:
assert len(b1.sheet_names()) == 1
del b1[0]
assert len(b1.sheet_names()) == 0
def test_add_book1(self):
"""
test this scenario: book3 = book1 + book2
@ -112,7 +105,7 @@ class TestAddBooks:
assert content[name] == self.content["Sheet2"]
elif "Sheet1" in name:
assert content[name] == self.content["Sheet1"]
def test_add_book1_in_place(self):
"""
test this scenario book1 += book2
@ -179,7 +172,7 @@ class TestAddBooks:
assert len(sheet_names) == 2
assert content["Sheet3"] == self.content["Sheet3"]
assert content["Sheet1"] == self.content["Sheet1"]
def test_add_book4(self):
"""
test this scenario book3 = sheet1 + book
@ -205,14 +198,14 @@ class TestAddBooks:
b1 = pyexcel.BookReader(self.testfile)
try:
b1 + 12
assert 1==2
assert 1 == 2
except TypeError:
assert 1==1
assert 1 == 1
try:
b1 += 12
assert 1==2
assert 1 == 2
except TypeError:
assert 1==1
assert 1 == 1
def tearDown(self):
if os.path.exists(self.testfile):
@ -226,5 +219,18 @@ class TestMultiSheetReader:
self.testfile = "file_with_an_empty_sheet.xls"
def test_reader_with_correct_sheets(self):
r = pyexcel.BookReader(os.path.join("tests", "fixtures", self.testfile))
r = pyexcel.BookReader(os.path.join("tests",
"fixtures",
self.testfile))
assert r.number_of_sheets() == 3
def _produce_ordered_dict():
data_dict = OrderedDict()
data_dict.update({
"Sheet1": [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]]})
data_dict.update({
"Sheet2": [[4, 4, 4, 4], [5, 5, 5, 5], [6, 6, 6, 6]]})
data_dict.update({
"Sheet3": [[u'X', u'Y', u'Z'], [1, 4, 7], [2, 5, 8], [3, 6, 9]]})
return data_dict

View File

@ -1,10 +1,5 @@
import os
import sys
import pyexcel
if sys.version_info[0] < 3:
from StringIO import StringIO
else:
from io import BytesIO as StringIO
from base import create_sample_file1
@ -16,13 +11,12 @@ class TestStringIO:
with open(xlsfile, "rb") as f:
content = f.read()
r = pyexcel.get_sheet(file_type="xls", file_content=content)
result=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 1.1, 1]
result = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 1.1, 1]
actual = pyexcel.utils.to_array(r.enumerate())
assert result == actual
if os.path.exists(xlsfile):
os.unlink(xlsfile)
def test_xls_output_stringio(self):
data = [
[1, 2, 3],
@ -31,6 +25,6 @@ class TestStringIO:
io = pyexcel.save_as(dest_file_type="xls",
array=data)
r = pyexcel.get_sheet(file_type="xls", file_content=io.getvalue())
result=[1, 2, 3, 4, 5, 6]
result = [1, 2, 3, 4, 5, 6]
actual = pyexcel.utils.to_array(r.enumerate())
assert result == actual
assert result == actual

View File

@ -30,8 +30,8 @@ class TestNativeXLWriter:
class TestXLSnCSVWriter(PyexcelWriterBase):
def setUp(self):
self.testfile="test.xls"
self.testfile2="test.csv"
self.testfile = "test.xls"
self.testfile2 = "test.csv"
def tearDown(self):
if os.path.exists(self.testfile):
@ -42,7 +42,7 @@ class TestXLSnCSVWriter(PyexcelWriterBase):
class TestXLSHatWriter(PyexcelHatWriterBase):
def setUp(self):
self.testfile="test.xls"
self.testfile = "test.xls"
def tearDown(self):
if os.path.exists(self.testfile):