New style io (#36)
* 🎉 new style reader * 🎉 new style writer and reader plugins * This is an auto-commit, updating project meta data, such as changelog.rst, contributors.rst * 💚 update moban update * This is an auto-commit, updating project meta data, such as changelog.rst, contributors.rst * 💚 use pyexcel-io dev branch * 📚 update PR template * 🐴 code refactoring Co-authored-by: chfw <chfw@users.noreply.github.com>
This commit is contained in:
parent
25647ac365
commit
d3b57b434b
|
@ -1,11 +1,9 @@
|
||||||
With your PR, here is a check list:
|
With your PR, here is a check list:
|
||||||
|
|
||||||
- [ ] Has Test cases written
|
- [ ] Has test cases written?
|
||||||
- [ ] Has all code lines tested
|
- [ ] Has all code lines tested?
|
||||||
- [ ] Has `make format` been run?
|
- [ ] Has `make format` been run?
|
||||||
- [ ] Please update CHANGELOG.yml(not CHANGELOG.rst)
|
- [ ] Please update CHANGELOG.yml(not CHANGELOG.rst)
|
||||||
- [ ] Passes all Travis CI builds
|
- [ ] Passes all Travis CI builds
|
||||||
- [ ] Has fair amount of documentation if your change is complex
|
- [ ] Has fair amount of documentation if your change is complex
|
||||||
- [ ] run 'make format' so as to confirm the pyexcel organisation's coding style
|
|
||||||
- [ ] Please add yourself to 'contributors' section of pyexcel-xls.yml (if not found, please use CONTRIBUTORS.rst)
|
|
||||||
- [ ] Agree on NEW BSD License for your contribution
|
- [ ] Agree on NEW BSD License for your contribution
|
||||||
|
|
|
@ -5,23 +5,25 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: synchronize templates via moban
|
name: synchronize templates via moban
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v1
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: '3.7'
|
python-version: '3.7'
|
||||||
- name: check changes
|
- name: check changes
|
||||||
run: |
|
run: |
|
||||||
pip install moban gitfs2 pypifs
|
pip install moban gitfs2 pypifs moban-jinja2-github moban-ansible
|
||||||
moban
|
moban
|
||||||
git status
|
git status
|
||||||
git diff --exit-code
|
git diff --exit-code
|
||||||
- name: Auto-commit
|
- name: Auto-commit
|
||||||
if: failure()
|
if: failure()
|
||||||
uses: docker://cdssnc/auto-commit-github-action
|
uses: docker://cdssnc/auto-commit-github-action
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
args: This is an auto-commit, updating project meta data, such as changelog.rst, contributors.rst
|
args: >-
|
||||||
|
This is an auto-commit, updating project meta data,
|
||||||
|
such as changelog.rst, contributors.rst
|
||||||
|
|
|
@ -540,3 +540,7 @@ cscope.files
|
||||||
cscope.out
|
cscope.out
|
||||||
cscope.in.out
|
cscope.in.out
|
||||||
cscope.po.out
|
cscope.po.out
|
||||||
|
|
||||||
|
|
||||||
|
# remove moban hash dictionary
|
||||||
|
.moban.hashes
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
In alphabetical order:
|
In alphabetical order:
|
||||||
|
|
||||||
* `John Vandenberg <https://api.github.com/users/jayvdb>`_
|
* `John Vandenberg <https://github.com/jayvdb>`_
|
||||||
|
|
3
Makefile
3
Makefile
|
@ -6,9 +6,6 @@ test: lint
|
||||||
install_test:
|
install_test:
|
||||||
pip install -r tests/requirements.txt
|
pip install -r tests/requirements.txt
|
||||||
|
|
||||||
git-diff-check:
|
|
||||||
git diff --exit-code
|
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
bash lint.sh
|
bash lint.sh
|
||||||
|
|
||||||
|
|
3
lint.sh
3
lint.sh
|
@ -1,3 +1,2 @@
|
||||||
pip install flake8
|
pip install flake8
|
||||||
flake8 . --exclude=.moban.d,docs,setup.py --builtins=unicode,xrange,long
|
flake8 --exclude=.moban.d,docs,setup.py --builtins=unicode,xrange,long . && python setup.py checkdocs
|
||||||
python setup.py checkdocs
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
The lower level xls/xlsx/xlsm file format handler using xlrd/xlwt
|
The lower level xls/xlsx/xlsm file format handler using xlrd/xlwt
|
||||||
|
|
||||||
:copyright: (c) 2016-2017 by Onni Software Ltd
|
:copyright: (c) 2016-2020 by Onni Software Ltd
|
||||||
:license: New BSD License
|
:license: New BSD License
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -15,15 +15,28 @@ from pyexcel_io.io import save_data as write_data
|
||||||
|
|
||||||
# this line has to be place above all else
|
# this line has to be place above all else
|
||||||
# because of dynamic import
|
# because of dynamic import
|
||||||
from pyexcel_io.plugins import IOPluginInfoChain
|
from pyexcel_io.plugins import IOPluginInfoChainV2
|
||||||
|
|
||||||
__FILE_TYPE__ = "xls"
|
__FILE_TYPE__ = "xls"
|
||||||
IOPluginInfoChain(__name__).add_a_reader(
|
|
||||||
relative_plugin_class_path="xlsr.XLSBook",
|
IOPluginInfoChainV2(__name__).add_a_reader(
|
||||||
|
relative_plugin_class_path="xlsr.XLSInFile",
|
||||||
|
locations=["file"],
|
||||||
|
file_types=[__FILE_TYPE__, "xlsx", "xlsm"],
|
||||||
|
stream_type="binary",
|
||||||
|
).add_a_reader(
|
||||||
|
relative_plugin_class_path="xlsr.XLSInMemory",
|
||||||
|
locations=["memory"],
|
||||||
|
file_types=[__FILE_TYPE__, "xlsx", "xlsm"],
|
||||||
|
stream_type="binary",
|
||||||
|
).add_a_reader(
|
||||||
|
relative_plugin_class_path="xlsr.XLSInContent",
|
||||||
|
locations=["content"],
|
||||||
file_types=[__FILE_TYPE__, "xlsx", "xlsm"],
|
file_types=[__FILE_TYPE__, "xlsx", "xlsm"],
|
||||||
stream_type="binary",
|
stream_type="binary",
|
||||||
).add_a_writer(
|
).add_a_writer(
|
||||||
relative_plugin_class_path="xlsw.XLSWriter",
|
relative_plugin_class_path="xlsw.XLSWriter",
|
||||||
|
locations=["file", "memory"],
|
||||||
file_types=[__FILE_TYPE__],
|
file_types=[__FILE_TYPE__],
|
||||||
stream_type="binary",
|
stream_type="binary",
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,17 +4,16 @@
|
||||||
|
|
||||||
The lower level xls/xlsm file format handler using xlrd
|
The lower level xls/xlsm file format handler using xlrd
|
||||||
|
|
||||||
:copyright: (c) 2016-2017 by Onni Software Ltd
|
:copyright: (c) 2016-2020 by Onni Software Ltd
|
||||||
:license: New BSD License
|
:license: New BSD License
|
||||||
"""
|
"""
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import xlrd
|
import xlrd
|
||||||
|
|
||||||
from pyexcel_io.book import BookReader
|
|
||||||
from pyexcel_io.sheet import SheetReader
|
|
||||||
from pyexcel_io.service import has_no_digits_in_float
|
from pyexcel_io.service import has_no_digits_in_float
|
||||||
from pyexcel_io._compact import OrderedDict, irange
|
from pyexcel_io._compact import irange
|
||||||
|
from pyexcel_io.plugin_api.abstract_sheet import ISheet
|
||||||
|
from pyexcel_io.plugin_api.abstract_reader import IReader
|
||||||
|
|
||||||
XLS_KEYWORDS = [
|
XLS_KEYWORDS = [
|
||||||
"filename",
|
"filename",
|
||||||
|
@ -45,7 +44,7 @@ class MergedCell(object):
|
||||||
registry[key] = self
|
registry[key] = self
|
||||||
|
|
||||||
|
|
||||||
class XLSheet(SheetReader):
|
class XLSheet(ISheet):
|
||||||
"""
|
"""
|
||||||
xls, xlsx, xlsm sheet reader
|
xls, xlsx, xlsm sheet reader
|
||||||
|
|
||||||
|
@ -53,12 +52,13 @@ class XLSheet(SheetReader):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sheet, auto_detect_int=True, date_mode=0, **keywords):
|
def __init__(self, sheet, auto_detect_int=True, date_mode=0, **keywords):
|
||||||
SheetReader.__init__(self, sheet, **keywords)
|
|
||||||
self.__auto_detect_int = auto_detect_int
|
self.__auto_detect_int = auto_detect_int
|
||||||
self.__hidden_cols = []
|
self.__hidden_cols = []
|
||||||
self.__hidden_rows = []
|
self.__hidden_rows = []
|
||||||
self.__merged_cells = {}
|
self.__merged_cells = {}
|
||||||
self._book_date_mode = date_mode
|
self._book_date_mode = date_mode
|
||||||
|
self._native_sheet = sheet
|
||||||
|
self._keywords = keywords
|
||||||
if keywords.get("detect_merged_cells") is True:
|
if keywords.get("detect_merged_cells") is True:
|
||||||
for merged_cell_ranges in sheet.merged_cells:
|
for merged_cell_ranges in sheet.merged_cells:
|
||||||
merged_cells = MergedCell(*merged_cell_ranges)
|
merged_cells = MergedCell(*merged_cell_ranges)
|
||||||
|
@ -75,17 +75,14 @@ class XLSheet(SheetReader):
|
||||||
def name(self):
|
def name(self):
|
||||||
return self._native_sheet.name
|
return self._native_sheet.name
|
||||||
|
|
||||||
def number_of_rows(self):
|
def row_iterator(self):
|
||||||
"""
|
number_of_rows = self._native_sheet.nrows - len(self.__hidden_rows)
|
||||||
Number of rows in the xls sheet
|
return range(number_of_rows)
|
||||||
"""
|
|
||||||
return self._native_sheet.nrows - len(self.__hidden_rows)
|
|
||||||
|
|
||||||
def number_of_columns(self):
|
def column_iterator(self, row):
|
||||||
"""
|
number_of_columns = self._native_sheet.ncols - len(self.__hidden_cols)
|
||||||
Number of columns in the xls sheet
|
for column in range(number_of_columns):
|
||||||
"""
|
yield self.cell_value(row, column)
|
||||||
return self._native_sheet.ncols - len(self.__hidden_cols)
|
|
||||||
|
|
||||||
def cell_value(self, row, column):
|
def cell_value(self, row, column):
|
||||||
"""
|
"""
|
||||||
|
@ -127,93 +124,48 @@ def calculate_offsets(incoming_index, hidden_indices):
|
||||||
return incoming_index + offset
|
return incoming_index + offset
|
||||||
|
|
||||||
|
|
||||||
class XLSBook(BookReader):
|
class XLSReader(IReader):
|
||||||
"""
|
"""
|
||||||
XLSBook reader
|
XLSBook reader
|
||||||
|
|
||||||
It reads xls, xlsm, xlsx work book
|
It reads xls, xlsm, xlsx work book
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, file_type, **keywords):
|
||||||
BookReader.__init__(self)
|
|
||||||
self._file_content = None
|
|
||||||
self.__skip_hidden_sheets = True
|
|
||||||
self.__skip_hidden_row_column = True
|
|
||||||
self.__detect_merged_cells = False
|
|
||||||
|
|
||||||
def open(self, file_name, **keywords):
|
|
||||||
self.__parse_keywords(**keywords)
|
|
||||||
BookReader.open(self, file_name, **keywords)
|
|
||||||
|
|
||||||
def open_stream(self, file_stream, **keywords):
|
|
||||||
self.__parse_keywords(**keywords)
|
|
||||||
BookReader.open_stream(self, file_stream, **keywords)
|
|
||||||
|
|
||||||
def open_content(self, file_content, **keywords):
|
|
||||||
self.__parse_keywords(**keywords)
|
|
||||||
self._keywords = keywords
|
|
||||||
self._file_content = file_content
|
|
||||||
|
|
||||||
def __parse_keywords(self, **keywords):
|
|
||||||
self.__skip_hidden_sheets = keywords.get("skip_hidden_sheets", True)
|
self.__skip_hidden_sheets = keywords.get("skip_hidden_sheets", True)
|
||||||
self.__skip_hidden_row_column = keywords.get(
|
self.__skip_hidden_row_column = keywords.get(
|
||||||
"skip_hidden_row_and_column", True
|
"skip_hidden_row_and_column", True
|
||||||
)
|
)
|
||||||
self.__detect_merged_cells = keywords.get("detect_merged_cells", False)
|
self.__detect_merged_cells = keywords.get("detect_merged_cells", False)
|
||||||
|
self._keywords = keywords
|
||||||
|
xlrd_params = self._extract_xlrd_params()
|
||||||
|
if self.__skip_hidden_row_column and file_type == "xls":
|
||||||
|
xlrd_params["formatting_info"] = True
|
||||||
|
if self.__detect_merged_cells:
|
||||||
|
xlrd_params["formatting_info"] = True
|
||||||
|
|
||||||
|
self.content_array = []
|
||||||
|
self._native_book = self.get_xls_book(**xlrd_params)
|
||||||
|
for sheet in self._native_book.sheets():
|
||||||
|
if self.__skip_hidden_sheets and sheet.visibility != 0:
|
||||||
|
continue
|
||||||
|
self.content_array.append(sheet)
|
||||||
|
|
||||||
|
def read_sheet(self, index):
|
||||||
|
native_sheet = self.content_array[index]
|
||||||
|
sheet = XLSheet(
|
||||||
|
native_sheet,
|
||||||
|
date_mode=self._native_book.datemode,
|
||||||
|
**self._keywords
|
||||||
|
)
|
||||||
|
return sheet
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if self._native_book:
|
if self._native_book:
|
||||||
self._native_book.release_resources()
|
self._native_book.release_resources()
|
||||||
self._native_book = None
|
self._native_book = None
|
||||||
|
|
||||||
def read_sheet_by_index(self, sheet_index):
|
def get_xls_book(self, **xlrd_params):
|
||||||
self._native_book = self._get_book(on_demand=True)
|
|
||||||
sheet = self._native_book.sheet_by_index(sheet_index)
|
|
||||||
return self.read_sheet(sheet)
|
|
||||||
|
|
||||||
def read_sheet_by_name(self, sheet_name):
|
|
||||||
self._native_book = self._get_book(on_demand=True)
|
|
||||||
try:
|
|
||||||
sheet = self._native_book.sheet_by_name(sheet_name)
|
|
||||||
except xlrd.XLRDError:
|
|
||||||
raise ValueError("%s cannot be found" % sheet_name)
|
|
||||||
return self.read_sheet(sheet)
|
|
||||||
|
|
||||||
def read_all(self):
|
|
||||||
result = OrderedDict()
|
|
||||||
self._native_book = self._get_book()
|
|
||||||
for sheet in self._native_book.sheets():
|
|
||||||
if self.__skip_hidden_sheets and sheet.visibility != 0:
|
|
||||||
continue
|
|
||||||
data_dict = self.read_sheet(sheet)
|
|
||||||
result.update(data_dict)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def read_sheet(self, native_sheet):
|
|
||||||
sheet = XLSheet(
|
|
||||||
native_sheet,
|
|
||||||
date_mode=self._native_book.datemode,
|
|
||||||
**self._keywords
|
|
||||||
)
|
|
||||||
return {sheet.name: sheet.to_array()}
|
|
||||||
|
|
||||||
def _get_book(self, on_demand=False):
|
|
||||||
xlrd_params = self._extract_xlrd_params()
|
|
||||||
xlrd_params["on_demand"] = on_demand
|
|
||||||
|
|
||||||
if self._file_name:
|
|
||||||
xlrd_params["filename"] = self._file_name
|
|
||||||
elif self._file_stream:
|
|
||||||
file_content = self._file_stream.read()
|
|
||||||
xlrd_params["file_contents"] = file_content
|
|
||||||
elif self._file_content is not None:
|
|
||||||
xlrd_params["file_contents"] = self._file_content
|
|
||||||
else:
|
|
||||||
raise IOError("No valid file name or file content found.")
|
|
||||||
if self.__skip_hidden_row_column and self._file_type == "xls":
|
|
||||||
xlrd_params["formatting_info"] = True
|
|
||||||
if self.__detect_merged_cells:
|
|
||||||
xlrd_params["formatting_info"] = True
|
|
||||||
xls_book = xlrd.open_workbook(**xlrd_params)
|
xls_book = xlrd.open_workbook(**xlrd_params)
|
||||||
return xls_book
|
return xls_book
|
||||||
|
|
||||||
|
@ -226,6 +178,24 @@ class XLSBook(BookReader):
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
|
||||||
|
class XLSInFile(XLSReader):
|
||||||
|
def __init__(self, file_name, file_type, **keywords):
|
||||||
|
super().__init__(file_type, filename=file_name, **keywords)
|
||||||
|
|
||||||
|
|
||||||
|
class XLSInContent(XLSReader):
|
||||||
|
def __init__(self, file_content, file_type, **keywords):
|
||||||
|
super().__init__(file_type, file_contents=file_content, **keywords)
|
||||||
|
|
||||||
|
|
||||||
|
class XLSInMemory(XLSReader):
|
||||||
|
def __init__(self, file_stream, file_type, **keywords):
|
||||||
|
file_stream.seek(0)
|
||||||
|
super().__init__(
|
||||||
|
file_type, file_contents=file_stream.read(), **keywords
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def xldate_to_python_date(value, date_mode):
|
def xldate_to_python_date(value, date_mode):
|
||||||
"""
|
"""
|
||||||
convert xl date to python date
|
convert xl date to python date
|
||||||
|
|
|
@ -4,16 +4,15 @@
|
||||||
|
|
||||||
The lower level xls file format handler using xlwt
|
The lower level xls file format handler using xlwt
|
||||||
|
|
||||||
:copyright: (c) 2016-2017 by Onni Software Ltd
|
:copyright: (c) 2016-2020 by Onni Software Ltd
|
||||||
:license: New BSD License
|
:license: New BSD License
|
||||||
"""
|
"""
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import xlrd
|
import xlrd
|
||||||
from xlwt import XFStyle, Workbook
|
from xlwt import XFStyle, Workbook
|
||||||
|
|
||||||
from pyexcel_io.book import BookWriter
|
|
||||||
from pyexcel_io.sheet import SheetWriter
|
from pyexcel_io.sheet import SheetWriter
|
||||||
|
from pyexcel_io.plugin_api.abstract_writer import IWriter
|
||||||
|
|
||||||
DEFAULT_DATE_FORMAT = "DD/MM/YY"
|
DEFAULT_DATE_FORMAT = "DD/MM/YY"
|
||||||
DEFAULT_TIME_FORMAT = "HH:MM:SS"
|
DEFAULT_TIME_FORMAT = "HH:MM:SS"
|
||||||
|
@ -27,8 +26,7 @@ class XLSheetWriter(SheetWriter):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def set_sheet_name(self, name):
|
def set_sheet_name(self, name):
|
||||||
"""Create a sheet
|
"""Create a sheet"""
|
||||||
"""
|
|
||||||
self._native_sheet = self._native_book.add_sheet(name)
|
self._native_sheet = self._native_book.add_sheet(name)
|
||||||
self.current_row = 0
|
self.current_row = 0
|
||||||
|
|
||||||
|
@ -68,32 +66,33 @@ class XLSheetWriter(SheetWriter):
|
||||||
self.current_row += 1
|
self.current_row += 1
|
||||||
|
|
||||||
|
|
||||||
class XLSWriter(BookWriter):
|
class XLSWriter(IWriter):
|
||||||
"""
|
"""
|
||||||
xls writer
|
xls writer
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(
|
||||||
BookWriter.__init__(self)
|
self,
|
||||||
self.work_book = None
|
file_alike_object,
|
||||||
|
_, # file_type not used
|
||||||
def open(
|
encoding="ascii",
|
||||||
self, file_name, encoding="ascii", style_compression=2, **keywords
|
style_compression=2,
|
||||||
|
**keywords
|
||||||
):
|
):
|
||||||
BookWriter.open(self, file_name, **keywords)
|
self._file_alike_object = file_alike_object
|
||||||
self.work_book = Workbook(
|
self.work_book = Workbook(
|
||||||
style_compression=style_compression, encoding=encoding
|
style_compression=style_compression, encoding=encoding
|
||||||
)
|
)
|
||||||
|
|
||||||
def write(self, incoming_dict):
|
|
||||||
if incoming_dict:
|
|
||||||
BookWriter.write(self, incoming_dict)
|
|
||||||
else:
|
|
||||||
raise NotImplementedError(EMPTY_SHEET_NOT_ALLOWED)
|
|
||||||
|
|
||||||
def create_sheet(self, name):
|
def create_sheet(self, name):
|
||||||
return XLSheetWriter(self.work_book, None, name)
|
return XLSheetWriter(self.work_book, None, name)
|
||||||
|
|
||||||
|
def write(self, incoming_dict):
|
||||||
|
if incoming_dict:
|
||||||
|
IWriter.write(self, incoming_dict)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError(EMPTY_SHEET_NOT_ALLOWED)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""
|
"""
|
||||||
This call actually save the file
|
This call actually save the file
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
https://github.com/pyexcel/pyexcel-io/archive/master.zip
|
https://github.com/pyexcel/pyexcel-io/archive/dev.zip
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
import pyexcel as pe
|
import pyexcel as pe
|
||||||
from _compact import OrderedDict
|
from _compact import OrderedDict
|
||||||
|
@ -13,7 +14,6 @@ from pyexcel_xls import save_data
|
||||||
from pyexcel_xls.xlsr import xldate_to_python_date
|
from pyexcel_xls.xlsr import xldate_to_python_date
|
||||||
from pyexcel_xls.xlsw import XLSWriter as Writer
|
from pyexcel_xls.xlsw import XLSWriter as Writer
|
||||||
|
|
||||||
from mock import patch
|
|
||||||
from nose import SkipTest
|
from nose import SkipTest
|
||||||
from nose.tools import eq_, raises
|
from nose.tools import eq_, raises
|
||||||
|
|
||||||
|
@ -79,13 +79,11 @@ def test_issue_16_file_stream_has_no_getvalue():
|
||||||
|
|
||||||
@patch("xlrd.open_workbook")
|
@patch("xlrd.open_workbook")
|
||||||
def test_issue_18_encoding_override_isnt_passed(fake_open):
|
def test_issue_18_encoding_override_isnt_passed(fake_open):
|
||||||
fake_open.return_value = None
|
fake_open.return_value = MagicMock(sheets=MagicMock(return_value=[]))
|
||||||
test_encoding = "utf-32"
|
test_encoding = "utf-32"
|
||||||
from pyexcel_xls.xlsr import XLSBook
|
from pyexcel_xls.xlsr import XLSInFile
|
||||||
|
|
||||||
book = XLSBook()
|
XLSInFile("fake_file.xls", "xls", encoding_override=test_encoding)
|
||||||
book.open("fake_file.xls", encoding_override=test_encoding)
|
|
||||||
book._get_book()
|
|
||||||
keywords = fake_open.call_args[1]
|
keywords = fake_open.call_args[1]
|
||||||
assert keywords["encoding_override"] == test_encoding
|
assert keywords["encoding_override"] == test_encoding
|
||||||
|
|
||||||
|
@ -112,7 +110,7 @@ def test_empty_book_pyexcel_issue_120():
|
||||||
"""
|
"""
|
||||||
https://github.com/pyexcel/pyexcel/issues/120
|
https://github.com/pyexcel/pyexcel/issues/120
|
||||||
"""
|
"""
|
||||||
writer = Writer()
|
writer = Writer("fake.xls", "xls")
|
||||||
writer.write({})
|
writer.write({})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from nose.tools import eq_
|
|
||||||
from pyexcel_io import get_data, save_data
|
from pyexcel_io import get_data, save_data
|
||||||
|
|
||||||
|
from nose.tools import eq_
|
||||||
|
|
||||||
|
|
||||||
class TestFilter:
|
class TestFilter:
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from base import PyexcelWriterBase, PyexcelHatWriterBase
|
from base import PyexcelWriterBase, PyexcelHatWriterBase
|
||||||
from pyexcel_xls.xlsr import XLSBook as Reader
|
from pyexcel_xls.xlsr import XLSReader as Reader
|
||||||
from pyexcel_xls.xlsw import XLSWriter as Writer
|
from pyexcel_xls.xlsw import XLSWriter as Writer
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,12 +13,10 @@ class TestNativeXLSWriter:
|
||||||
"Sheet3": [[u"X", u"Y", u"Z"], [1, 4, 7], [2, 5, 8], [3, 6, 9]],
|
"Sheet3": [[u"X", u"Y", u"Z"], [1, 4, 7], [2, 5, 8], [3, 6, 9]],
|
||||||
}
|
}
|
||||||
self.testfile = "writer.xls"
|
self.testfile = "writer.xls"
|
||||||
writer = Writer()
|
writer = Writer(self.testfile, "xls")
|
||||||
writer.open(self.testfile)
|
|
||||||
writer.write(self.content)
|
writer.write(self.content)
|
||||||
writer.close()
|
writer.close()
|
||||||
reader = Reader()
|
reader = Reader("xls", filename=self.testfile)
|
||||||
reader.open(self.testfile)
|
|
||||||
content = reader.read_all()
|
content = reader.read_all()
|
||||||
for key in content.keys():
|
for key in content.keys():
|
||||||
content[key] = list(content[key])
|
content[key] = list(content[key])
|
||||||
|
|
Loading…
Reference in New Issue