Skip to content

Commit 6b1ada8

Browse files
committed
TST/DOC/BUG: Accommodate OpenPyXL incompatibility
* Detect whether a compatible version is installed * Skip openpyxl unit tests instead of failing * Inhibit registration of `openpyxl` engine in `ExcelWriter` * Raise `UserWarning` * Document limitation as a known issue * Resolve issue #7169
1 parent 4b17314 commit 6b1ada8

File tree

6 files changed

+51
-4
lines changed

6 files changed

+51
-4
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ pip install pandas
114114
- [xlrd/xlwt](http://www.python-excel.org/)
115115
- Excel reading (xlrd) and writing (xlwt)
116116
- [openpyxl](http://packages.python.org/openpyxl/)
117-
- openpyxl version 1.6.1 or higher, for writing .xlsx files
117+
- openpyxl version 1.6.1 or higher, but lower than 2.0.0, for
118+
writing .xlsx files
118119
- xlrd >= 0.9.0
119120
- [XlsxWriter](https://pypi.python.org/pypi/XlsxWriter)
120121
- Alternative Excel writer.

doc/source/install.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Optional Dependencies
9797
* `statsmodels <http://statsmodels.sourceforge.net/>`__
9898
* Needed for parts of :mod:`pandas.stats`
9999
* `openpyxl <http://packages.python.org/openpyxl/>`__, `xlrd/xlwt <http://www.python-excel.org/>`__
100-
* openpyxl version 1.6.1 or higher
100+
* openpyxl version 1.6.1 or higher, but lower than 2.0.0
101101
* Needed for Excel I/O
102102
* `XlsxWriter <https://pypi.python.org/pypi/XlsxWriter>`__
103103
* Alternative Excel writer.

doc/source/v0.14.0.txt

+10
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ users upgrade to this version.
3131

3232
- :ref:`Deprecations <whatsnew_0140.deprecations>`
3333

34+
- :ref:`Known Issues <whatsnew_0140.knownissues>`
35+
3436
- :ref:`Bug Fixes <release.bug_fixes-0.14.0>`
3537

3638
.. warning::
@@ -630,6 +632,14 @@ Deprecations
630632
in a future release. You can use the future behavior now by passing ``return_type='axes'``
631633
to boxplot.
632634

635+
.. _whatsnew_0140.knownissues:
636+
637+
Known Issues
638+
~~~~~~~~~~~~
639+
640+
- OpenPyXL 2.0.0 breaks backwards compatibility (:issue:`7196`)
641+
642+
633643
.. _whatsnew_0140.enhancements:
634644

635645
Enhancements

pandas/compat/openpyxl_compat.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
Detect incompatible version of OpenPyXL
3+
4+
GH7169
5+
"""
6+
7+
from distutils.version import LooseVersion
8+
9+
start_ver = '1.6.1'
10+
stop_ver = '2.0.0'
11+
12+
def is_compat():
13+
"""
14+
Detect whether the installed version of openpyxl is supported
15+
Returns True/False if openpyxl is installed, None otherwise
16+
"""
17+
try:
18+
import openpyxl
19+
except ImportError:
20+
return None
21+
22+
ver = LooseVersion(openpyxl.__version__)
23+
if ver < LooseVersion(start_ver) or LooseVersion(stop_ver) <= ver:
24+
return False
25+
26+
return True

pandas/io/excel.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from pandas.core import config
1717
from pandas.core.common import pprint_thing
1818
import pandas.compat as compat
19+
import pandas.compat.openpyxl_compat as openpyxl_compat
1920
import pandas.core.common as com
2021
from warnings import warn
2122
from distutils.version import LooseVersion
@@ -617,7 +618,12 @@ def _convert_to_style(cls, style_dict):
617618

618619
return xls_style
619620

620-
register_writer(_OpenpyxlWriter)
621+
622+
if openpyxl_compat.is_compat():
623+
register_writer(_OpenpyxlWriter)
624+
else:
625+
warn('Installed openpyxl is not supported at this time. Use >={} and <{}.'
626+
.format(openpyxl_compat.start_ver, openpyxl_compat.stop_ver))
621627

622628

623629
class _XlwtWriter(ExcelWriter):

pandas/io/tests/test_excel.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# pylint: disable=E1101
22

3-
from pandas.compat import u, range, map
3+
from pandas.compat import u, range, map, openpyxl_compat
44
from datetime import datetime, date, time
55
import os
66
from distutils.version import LooseVersion
@@ -45,6 +45,10 @@ def _skip_if_no_openpyxl():
4545
except ImportError:
4646
raise nose.SkipTest('openpyxl not installed, skipping')
4747

48+
if not openpyxl_compat.is_compat():
49+
raise nose.SkipTest('need %s <= openpyxl < %s, skipping' %
50+
(openpyxl_compat.start_ver, openpyxl_compat.stop_ver))
51+
4852

4953
def _skip_if_no_xlsxwriter():
5054
try:

0 commit comments

Comments
 (0)