Skip to content

DEP: bump min version of openpyxl to 3.0.0 #39603 #39702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Feb 15, 2021
2 changes: 1 addition & 1 deletion ci/deps/azure-37-locale_slow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dependencies:
- lxml
- matplotlib=3.0.0
- numpy=1.16.*
- openpyxl=2.6.0
- openpyxl=3.0.0
- python-dateutil
- python-blosc
- pytz=2017.3
Expand Down
2 changes: 1 addition & 1 deletion ci/deps/azure-37-minimum_versions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ dependencies:
- numba=0.46.0
- numexpr=2.6.8
- numpy=1.16.5
- openpyxl=2.6.0
- openpyxl=3.0.0
- pytables=3.5.1
- python-dateutil=2.7.3
- pytz=2017.3
Expand Down
2 changes: 1 addition & 1 deletion doc/source/getting_started/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ html5lib 1.0.1 HTML parser for read_html (see :ref
lxml 4.3.0 HTML parser for read_html (see :ref:`note <optional_html>`)
matplotlib 2.2.3 Visualization
numba 0.46.0 Alternative execution engine for rolling operations
openpyxl 2.6.0 Reading / writing for xlsx files
openpyxl 3.0.0 Reading / writing for xlsx files
pandas-gbq 0.12.0 Google Big Query access
psycopg2 2.7 PostgreSQL engine for sqlalchemy
pyarrow 0.15.0 Parquet, ORC, and feather reading / writing
Expand Down
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.3.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ Optional libraries below the lowest tested version may still work, but are not c
+-----------------+-----------------+---------+
| numba | 0.46.0 | |
+-----------------+-----------------+---------+
| openpyxl | 2.6.0 | |
| openpyxl | 3.0.0 | X |
+-----------------+-----------------+---------+
| pyarrow | 0.15.0 | |
+-----------------+-----------------+---------+
Expand Down
2 changes: 1 addition & 1 deletion pandas/compat/_optional.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"matplotlib": "2.2.3",
"numexpr": "2.6.8",
"odfpy": "1.3.0",
"openpyxl": "2.6.0",
"openpyxl": "3.0.0",
"pandas_gbq": "0.12.0",
"pyarrow": "0.15.0",
"pytest": "5.0.1",
Expand Down
16 changes: 6 additions & 10 deletions pandas/io/excel/_openpyxl.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from __future__ import annotations

from distutils.version import LooseVersion
import mmap
from typing import TYPE_CHECKING, Dict, List, Optional

import numpy as np

from pandas._typing import FilePathOrBuffer, Scalar, StorageOptions
from pandas.compat._optional import get_version, import_optional_dependency
from pandas.compat._optional import import_optional_dependency

from pandas.io.excel._base import BaseExcelReader, ExcelWriter
from pandas.io.excel._util import validate_freeze_panes
Expand Down Expand Up @@ -531,18 +530,15 @@ def _convert_cell(self, cell, convert_float: bool) -> Scalar:
return cell.value

def get_sheet_data(self, sheet, convert_float: bool) -> List[List[Scalar]]:
# GH 39001
# Reading of excel file depends on dimension data being correct but
# writers sometimes omit or get it wrong
import openpyxl

version = LooseVersion(get_version(openpyxl))

# There is no good way of determining if a sheet is read-only
# https://foss.heptapod.net/openpyxl/openpyxl/-/issues/1605
is_readonly = hasattr(sheet, "reset_dimensions")

if version >= "3.0.0" and is_readonly:
if is_readonly:
# GH 39001
# Reading of excel file depends on dimension data being correct but
# writers sometimes omit or get it wrong
sheet.reset_dimensions()

data: List[List[Scalar]] = []
Expand All @@ -556,7 +552,7 @@ def get_sheet_data(self, sheet, convert_float: bool) -> List[List[Scalar]]:
# Trim trailing empty rows
data = data[: last_row_with_data + 1]

if version >= "3.0.0" and is_readonly and len(data) > 0:
if is_readonly and len(data) > 0:
# With dimension reset, openpyxl no longer pads rows
max_width = max(len(data_row) for data_row in data)
if min(len(data_row) for data_row in data) < max_width:
Expand Down
11 changes: 0 additions & 11 deletions pandas/tests/io/excel/test_openpyxl.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
from distutils.version import LooseVersion
from pathlib import Path

import numpy as np
import pytest

from pandas.compat._optional import get_version

import pandas as pd
from pandas import DataFrame
import pandas._testing as tm
Expand Down Expand Up @@ -157,10 +154,6 @@ def test_read_with_bad_dimension(
datapath, ext, header, expected_data, filename, read_only, request
):
# GH 38956, 39001 - no/incorrect dimension information
version = LooseVersion(get_version(openpyxl))
if (read_only or read_only is None) and version < "3.0.0":
msg = "openpyxl read-only sheet is incorrect when dimension data is wrong"
request.node.add_marker(pytest.mark.xfail(reason=msg))
path = datapath("io", "data", "excel", f"{filename}{ext}")
if read_only is None:
result = pd.read_excel(path, header=header)
Expand Down Expand Up @@ -195,10 +188,6 @@ def test_append_mode_file(ext):
@pytest.mark.parametrize("read_only", [True, False, None])
def test_read_with_empty_trailing_rows(datapath, ext, read_only, request):
# GH 39181
version = LooseVersion(get_version(openpyxl))
if (read_only or read_only is None) and version < "3.0.0":
msg = "openpyxl read-only sheet is incorrect when dimension data is wrong"
request.node.add_marker(pytest.mark.xfail(reason=msg))
path = datapath("io", "data", "excel", f"empty_trailing_rows{ext}")
if read_only is None:
result = pd.read_excel(path)
Expand Down