From e895c6a969ff237b46699490477ed92c2c140c37 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Fri, 26 May 2017 07:48:05 -0500 Subject: [PATCH] TST: Fix excel test discovery (#16478) * TST: Fix excel test discovery * BUG: Handle sheetname deprecation directly Since sheetname=None has a special meaning, we can't use the deprecate_kwargs decorator. We instead handle it in read_excel. * TST/BUG: Ensure pathlib roundtrip uses right params Reader / writer may depend on filename and engine. Set these on the reader and writer before round-tripping. --- pandas/io/excel.py | 13 +++++++-- pandas/tests/io/test_excel.py | 51 +++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/pandas/io/excel.py b/pandas/io/excel.py index 81a36b21b36171..aa08e5fd378f05 100644 --- a/pandas/io/excel.py +++ b/pandas/io/excel.py @@ -8,6 +8,7 @@ import os import abc +import warnings import numpy as np from pandas.core.dtypes.common import ( @@ -30,7 +31,7 @@ import pandas.compat.openpyxl_compat as openpyxl_compat from warnings import warn from distutils.version import LooseVersion -from pandas.util._decorators import Appender, deprecate_kwarg +from pandas.util._decorators import Appender from textwrap import fill __all__ = ["read_excel", "ExcelWriter", "ExcelFile"] @@ -193,7 +194,6 @@ def get_writer(engine_name): raise ValueError("No Excel writer '%s'" % engine_name) -@deprecate_kwarg('sheetname', 'sheet_name') @Appender(_read_excel_doc) def read_excel(io, sheet_name=0, header=0, skiprows=None, skip_footer=0, index_col=None, names=None, parse_cols=None, parse_dates=False, @@ -202,6 +202,15 @@ def read_excel(io, sheet_name=0, header=0, skiprows=None, skip_footer=0, dtype=None, true_values=None, false_values=None, engine=None, squeeze=False, **kwds): + # Can't use _deprecate_kwarg since sheetname=None has a special meaning + if is_integer(sheet_name) and sheet_name == 0 and 'sheetname' in kwds: + warnings.warn("The `sheetname` keyword is deprecated, use " + "`sheet_name` instead", FutureWarning, stacklevel=2) + sheet_name = kwds.pop("sheetname") + elif 'sheetname' in kwds: + raise TypeError("Cannot specify both `sheet_name` and `sheetname`. " + "Use just `sheet_name`") + if not isinstance(io, ExcelFile): io = ExcelFile(io, engine=engine) diff --git a/pandas/tests/io/test_excel.py b/pandas/tests/io/test_excel.py index 0a79d4e8fd81be..4441ed815370b9 100644 --- a/pandas/tests/io/test_excel.py +++ b/pandas/tests/io/test_excel.py @@ -5,6 +5,7 @@ import sys import os from distutils.version import LooseVersion +from functools import partial import warnings from warnings import catch_warnings @@ -407,7 +408,7 @@ def test_reading_all_sheets(self): # Ensure a dict is returned. # See PR #9450 basename = 'test_multisheet' - dfs = self.get_exceldf(basename, sheetname=None) + dfs = self.get_exceldf(basename, sheet_name=None) # ensure this is not alphabetical to test order preservation expected_keys = ['Charlie', 'Alpha', 'Beta'] tm.assert_contains_all(expected_keys, dfs.keys()) @@ -424,7 +425,7 @@ def test_reading_multiple_specific_sheets(self): basename = 'test_multisheet' # Explicitly request duplicates. Only the set should be returned. expected_keys = [2, 'Charlie', 'Charlie'] - dfs = self.get_exceldf(basename, sheetname=expected_keys) + dfs = self.get_exceldf(basename, sheet_name=expected_keys) expected_keys = list(set(expected_keys)) tm.assert_contains_all(expected_keys, dfs.keys()) assert len(expected_keys) == len(dfs.keys()) @@ -434,7 +435,7 @@ def test_reading_all_sheets_with_blank(self): # In the case where some sheets are blank. # Issue #11711 basename = 'blank_with_header' - dfs = self.get_exceldf(basename, sheetname=None) + dfs = self.get_exceldf(basename, sheet_name=None) expected_keys = ['Sheet1', 'Sheet2', 'Sheet3'] tm.assert_contains_all(expected_keys, dfs.keys()) @@ -551,11 +552,15 @@ def test_sheet_name_and_sheetname(self): dfref = self.get_csv_refdf('test1') df1 = self.get_exceldf('test1', sheet_name='Sheet1') # doc with tm.assert_produces_warning(FutureWarning, check_stacklevel=False): - df2 = self.get_exceldf('test1', sheetname='Sheet2') # bkwrd compat + df2 = self.get_exceldf('test1', sheetname='Sheet1') # bkwrd compat tm.assert_frame_equal(df1, dfref, check_names=False) tm.assert_frame_equal(df2, dfref, check_names=False) + def test_sheet_name_both_raises(self): + with tm.assert_raises_regex(TypeError, "Cannot specify both"): + self.get_exceldf('test1', sheetname='Sheet1', sheet_name='Sheet1') + class XlrdTests(ReadingTestsBase): """ @@ -589,7 +594,7 @@ def test_read_xlrd_Book(self): result = read_excel(xl, "SheetA") tm.assert_frame_equal(df, result) - result = read_excel(book, sheetname="SheetA", engine="xlrd") + result = read_excel(book, sheet_name="SheetA", engine="xlrd") tm.assert_frame_equal(df, result) @tm.network @@ -691,7 +696,7 @@ def tdf(sheetname): with ExcelWriter(pth) as ew: for sheetname, df in iteritems(dfs): df.to_excel(ew, sheetname) - dfs_returned = read_excel(pth, sheetname=sheets) + dfs_returned = read_excel(pth, sheet_name=sheets) for s in sheets: tm.assert_frame_equal(dfs[s], dfs_returned[s]) @@ -1001,19 +1006,19 @@ def test_read_excel_squeeze(self): tm.assert_series_equal(actual, expected) -class XlsReaderTests(XlrdTests): +class TestXlsReaderTests(XlrdTests): ext = '.xls' engine_name = 'xlrd' check_skip = staticmethod(_skip_if_no_xlrd) -class XlsxReaderTests(XlrdTests): +class TestXlsxReaderTests(XlrdTests): ext = '.xlsx' engine_name = 'xlrd' check_skip = staticmethod(_skip_if_no_xlrd) -class XlsmReaderTests(XlrdTests): +class TestXlsmReaderTests(XlrdTests): ext = '.xlsm' engine_name = 'xlrd' check_skip = staticmethod(_skip_if_no_xlrd) @@ -1872,12 +1877,18 @@ def test_freeze_panes(self): def test_path_pathlib(self): df = tm.makeDataFrame() - result = tm.round_trip_pathlib(df.to_excel, pd.read_excel) + writer = partial(df.to_excel, engine=self.engine_name) + reader = partial(pd.read_excel) + result = tm.round_trip_pathlib(writer, reader, + path="foo.{}".format(self.ext)) tm.assert_frame_equal(df, result) def test_path_localpath(self): df = tm.makeDataFrame() - result = tm.round_trip_localpath(df.to_excel, pd.read_excel) + writer = partial(df.to_excel, engine=self.engine_name) + reader = partial(pd.read_excel) + result = tm.round_trip_pathlib(writer, reader, + path="foo.{}".format(self.ext)) tm.assert_frame_equal(df, result) @@ -1909,7 +1920,7 @@ def versioned_raise_on_incompat_version(cls): @raise_on_incompat_version(1) -class OpenpyxlTests(ExcelWriterBase): +class TestOpenpyxlTests(ExcelWriterBase): ext = '.xlsx' engine_name = 'openpyxl1' check_skip = staticmethod(lambda *args, **kwargs: None) @@ -1962,7 +1973,7 @@ def setup_class(cls): @raise_on_incompat_version(2) @skip_openpyxl_gt21 -class Openpyxl20Tests(ExcelWriterBase): +class TestOpenpyxl20Tests(ExcelWriterBase): ext = '.xlsx' engine_name = 'openpyxl20' check_skip = staticmethod(lambda *args, **kwargs: None) @@ -2078,7 +2089,7 @@ def setup_class(cls): @raise_on_incompat_version(2) @skip_openpyxl_lt22 -class Openpyxl22Tests(ExcelWriterBase): +class TestOpenpyxl22Tests(ExcelWriterBase): ext = '.xlsx' engine_name = 'openpyxl22' check_skip = staticmethod(lambda *args, **kwargs: None) @@ -2173,7 +2184,7 @@ def test_write_cells_merge_styled(self): assert xcell_a2.font == openpyxl_sty_merged -class XlwtTests(ExcelWriterBase): +class TestXlwtTests(ExcelWriterBase): ext = '.xls' engine_name = 'xlwt' check_skip = staticmethod(_skip_if_no_xlwt) @@ -2230,7 +2241,7 @@ def test_to_excel_styleconverter(self): assert xlwt.Alignment.VERT_TOP == xls_style.alignment.vert -class XlsxWriterTests(ExcelWriterBase): +class TestXlsxWriterTests(ExcelWriterBase): ext = '.xlsx' engine_name = 'xlsxwriter' check_skip = staticmethod(_skip_if_no_xlsxwriter) @@ -2283,7 +2294,7 @@ def test_column_format(self): assert read_num_format == num_format -class OpenpyxlTests_NoMerge(ExcelWriterBase): +class TestOpenpyxlTests_NoMerge(ExcelWriterBase): ext = '.xlsx' engine_name = 'openpyxl' check_skip = staticmethod(_skip_if_no_openpyxl) @@ -2292,7 +2303,7 @@ class OpenpyxlTests_NoMerge(ExcelWriterBase): merge_cells = False -class XlwtTests_NoMerge(ExcelWriterBase): +class TestXlwtTests_NoMerge(ExcelWriterBase): ext = '.xls' engine_name = 'xlwt' check_skip = staticmethod(_skip_if_no_xlwt) @@ -2301,7 +2312,7 @@ class XlwtTests_NoMerge(ExcelWriterBase): merge_cells = False -class XlsxWriterTests_NoMerge(ExcelWriterBase): +class TestXlsxWriterTests_NoMerge(ExcelWriterBase): ext = '.xlsx' engine_name = 'xlsxwriter' check_skip = staticmethod(_skip_if_no_xlsxwriter) @@ -2310,7 +2321,7 @@ class XlsxWriterTests_NoMerge(ExcelWriterBase): merge_cells = False -class ExcelWriterEngineTests(object): +class TestExcelWriterEngineTests(object): def test_ExcelWriter_dispatch(self): with tm.assert_raises_regex(ValueError, 'No engine'):