From f48de698f26a50ea0a048f58ef006a6648a0e73b Mon Sep 17 00:00:00 2001 From: Mike Robinson Date: Sat, 2 Nov 2019 18:16:11 +0000 Subject: [PATCH 1/7] Deprecate using `xlrd` engine --- pandas/io/excel/_base.py | 10 ++++++++-- pandas/tests/io/excel/test_xlrd.py | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/pandas/io/excel/_base.py b/pandas/io/excel/_base.py index e615507b4199d..2f0448d9ac446 100644 --- a/pandas/io/excel/_base.py +++ b/pandas/io/excel/_base.py @@ -4,6 +4,7 @@ from io import BytesIO import os from textwrap import fill +import warnings from pandas._config import config @@ -784,7 +785,7 @@ def close(self): class ExcelFile: """ Class for parsing tabular excel sheets into DataFrame objects. - Uses xlrd. See read_excel for more documentation + Uses xlrd, openpyxl or odf. See read_excel for more documentation Parameters ---------- @@ -804,8 +805,13 @@ class ExcelFile: _engines = {"xlrd": _XlrdReader, "openpyxl": _OpenpyxlReader, "odf": _ODFReader} def __init__(self, io, engine=None): - if engine is None: + if engine == "xlrd" or engine is None: engine = "xlrd" + warnings.warn( + "xlrd is deprecated. Alternative supported engines: 'openpyxl' or 'odf'.", + FutureWarning, + stacklevel=2, + ) if engine not in self._engines: raise ValueError("Unknown engine: {engine}".format(engine=engine)) diff --git a/pandas/tests/io/excel/test_xlrd.py b/pandas/tests/io/excel/test_xlrd.py index e04dfc97d4968..a628967e3336e 100644 --- a/pandas/tests/io/excel/test_xlrd.py +++ b/pandas/tests/io/excel/test_xlrd.py @@ -39,3 +39,19 @@ def test_excel_table_sheet_by_index(datapath, read_ext): with pd.ExcelFile(path) as excel: with pytest.raises(xlrd.XLRDError): pd.read_excel(excel, "asdf") + + +def test_excel_file_warning_with_default_engine(datapath): + path = datapath("io", "data", "test1.xls") + with tm.assert_produces_warning( + FutureWarning, check_stacklevel=False, raise_on_extra_warnings=False + ): + pd.ExcelFile(path) + + +def test_read_excel_warning_with_default_engine(tmpdir, datapath): + path = datapath("io", "data", "test1.xls") + with tm.assert_produces_warning( + FutureWarning, check_stacklevel=False, raise_on_extra_warnings=False + ): + pd.read_excel(path, "Sheet1") From af0a535aea9f4c077df21516c290d3f7c6f7707d Mon Sep 17 00:00:00 2001 From: Mike Robinson Date: Sun, 3 Nov 2019 09:06:00 +0000 Subject: [PATCH 2/7] Fix pep8 --- pandas/io/excel/_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/excel/_base.py b/pandas/io/excel/_base.py index 2f0448d9ac446..4eedeb17d491a 100644 --- a/pandas/io/excel/_base.py +++ b/pandas/io/excel/_base.py @@ -808,7 +808,7 @@ def __init__(self, io, engine=None): if engine == "xlrd" or engine is None: engine = "xlrd" warnings.warn( - "xlrd is deprecated. Alternative supported engines: 'openpyxl' or 'odf'.", + "xlrd is deprecated. Maintained engines: 'openpyxl' or 'odf'.", FutureWarning, stacklevel=2, ) From a6d5825c63a528a1f6a1fd0bdab0cae292caa552 Mon Sep 17 00:00:00 2001 From: Mike Date: Wed, 6 Nov 2019 19:44:04 +0000 Subject: [PATCH 3/7] Fixes based on review --- pandas/io/excel/_base.py | 4 ++-- pandas/tests/io/excel/test_xlrd.py | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/pandas/io/excel/_base.py b/pandas/io/excel/_base.py index 4eedeb17d491a..9a70f4aa1e8b9 100644 --- a/pandas/io/excel/_base.py +++ b/pandas/io/excel/_base.py @@ -808,9 +808,9 @@ def __init__(self, io, engine=None): if engine == "xlrd" or engine is None: engine = "xlrd" warnings.warn( - "xlrd is deprecated. Maintained engines: 'openpyxl' or 'odf'.", + 'The Excel reader engine will default to "openpyxl" in the future. \ + Specify engine="openpyxl" to suppress this warning.', FutureWarning, - stacklevel=2, ) if engine not in self._engines: raise ValueError("Unknown engine: {engine}".format(engine=engine)) diff --git a/pandas/tests/io/excel/test_xlrd.py b/pandas/tests/io/excel/test_xlrd.py index a628967e3336e..495d370560e92 100644 --- a/pandas/tests/io/excel/test_xlrd.py +++ b/pandas/tests/io/excel/test_xlrd.py @@ -41,17 +41,15 @@ def test_excel_table_sheet_by_index(datapath, read_ext): pd.read_excel(excel, "asdf") +# See issue #29375 def test_excel_file_warning_with_default_engine(datapath): path = datapath("io", "data", "test1.xls") - with tm.assert_produces_warning( - FutureWarning, check_stacklevel=False, raise_on_extra_warnings=False - ): + with tm.assert_produces_warning(FutureWarning): pd.ExcelFile(path) +# See issue #29375 def test_read_excel_warning_with_default_engine(tmpdir, datapath): path = datapath("io", "data", "test1.xls") - with tm.assert_produces_warning( - FutureWarning, check_stacklevel=False, raise_on_extra_warnings=False - ): + with tm.assert_produces_warning(FutureWarning): pd.read_excel(path, "Sheet1") From c1327c0b6fc6f4a55379782c1f96c2976150f853 Mon Sep 17 00:00:00 2001 From: Mike Date: Wed, 6 Nov 2019 19:46:40 +0000 Subject: [PATCH 4/7] Fix based on review --- pandas/io/excel/_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/excel/_base.py b/pandas/io/excel/_base.py index 9a70f4aa1e8b9..0efb990e3a0bf 100644 --- a/pandas/io/excel/_base.py +++ b/pandas/io/excel/_base.py @@ -805,7 +805,7 @@ class ExcelFile: _engines = {"xlrd": _XlrdReader, "openpyxl": _OpenpyxlReader, "odf": _ODFReader} def __init__(self, io, engine=None): - if engine == "xlrd" or engine is None: + if engine is None: engine = "xlrd" warnings.warn( 'The Excel reader engine will default to "openpyxl" in the future. \ From 8bc9419973676294a613479ae0fa1fb895f9faf9 Mon Sep 17 00:00:00 2001 From: Mike Robinson Date: Tue, 24 Dec 2019 18:26:29 +0000 Subject: [PATCH 5/7] Changes to test to prevent warnings in tests --- pandas/tests/io/excel/test_xlrd.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/pandas/tests/io/excel/test_xlrd.py b/pandas/tests/io/excel/test_xlrd.py index 495d370560e92..5d011f1f843bf 100644 --- a/pandas/tests/io/excel/test_xlrd.py +++ b/pandas/tests/io/excel/test_xlrd.py @@ -1,3 +1,5 @@ +import warnings + import pytest import pandas as pd @@ -24,7 +26,6 @@ def test_read_xlrd_book(read_ext, frame): with tm.ensure_clean(read_ext) as pth: df.to_excel(pth, sheet_name) book = xlrd.open_workbook(pth) - with ExcelFile(book, engine=engine) as xl: result = pd.read_excel(xl, sheet_name, index_col=0) tm.assert_frame_equal(df, result) @@ -36,20 +37,24 @@ def test_read_xlrd_book(read_ext, frame): # TODO: test for openpyxl as well def test_excel_table_sheet_by_index(datapath, read_ext): path = datapath("io", "data", "excel", "test1{}".format(read_ext)) - with pd.ExcelFile(path) as excel: - with pytest.raises(xlrd.XLRDError): - pd.read_excel(excel, "asdf") + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + with pd.ExcelFile(path) as excel: + with pytest.raises(xlrd.XLRDError): + pd.read_excel(excel, "asdf") # See issue #29375 def test_excel_file_warning_with_default_engine(datapath): - path = datapath("io", "data", "test1.xls") - with tm.assert_produces_warning(FutureWarning): + path = datapath("io", "data", "excel", "test1.xls") + with warnings.catch_warnings(record=True) as w: pd.ExcelFile(path) + assert "default to \"openpyxl\" in the future." in str(w[-1].message) # See issue #29375 def test_read_excel_warning_with_default_engine(tmpdir, datapath): - path = datapath("io", "data", "test1.xls") - with tm.assert_produces_warning(FutureWarning): + path = datapath("io", "data", "excel", "test1.xls") + with warnings.catch_warnings(record=True) as w: pd.read_excel(path, "Sheet1") + assert "default to \"openpyxl\" in the future." in str(w[-1].message) From 3073f5a263f680237ef51cb57a51bfece7c99338 Mon Sep 17 00:00:00 2001 From: Mike Robinson Date: Sun, 26 Jan 2020 15:26:12 +0000 Subject: [PATCH 6/7] Add in deprecation msg for (#28547) --- doc/source/whatsnew/v1.1.0.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 920919755dc23..07baed9a57a3f 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -68,7 +68,8 @@ Backwards incompatible API changes Deprecations ~~~~~~~~~~~~ - +-:func:`read_excel` engine argument "xlrd" will no longer be the default engine and +will be replaced by "openpyxl" in a future version (:issue:`28547`). - - From a1bb8704431dd9da1cab7eccdcb49a88d6f6aaad Mon Sep 17 00:00:00 2001 From: Mike Robinson Date: Sun, 26 Jan 2020 16:35:57 +0000 Subject: [PATCH 7/7] fixup! Add in deprecation msg for (#28547) --- doc/source/whatsnew/v1.1.0.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 07baed9a57a3f..e1b99bfcbaaf6 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -68,8 +68,8 @@ Backwards incompatible API changes Deprecations ~~~~~~~~~~~~ --:func:`read_excel` engine argument "xlrd" will no longer be the default engine and -will be replaced by "openpyxl" in a future version (:issue:`28547`). +- :func:`read_excel` engine argument "xlrd" will no longer be the default engine and + will be replaced by "openpyxl" in a future version (:issue:`28547`). - -