From 1f8e9a4387a0cbffd4fc2df251874576c5bedfd6 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 6 Jul 2021 12:40:38 -0700 Subject: [PATCH] Backport PR #42394: REGR: unpickling in 1.3.0 DataFrame created in 1.2.x #42345 --- doc/source/whatsnew/v1.3.1.rst | 1 + pandas/_libs/internals.pyx | 7 ++++++- .../1.2.4/empty_frame_v1_2_4-GH#42345.pkl | Bin 0 -> 501 bytes pandas/tests/io/test_pickle.py | 16 +++++++++++++--- 4 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 pandas/tests/io/data/legacy_pickle/1.2.4/empty_frame_v1_2_4-GH#42345.pkl diff --git a/doc/source/whatsnew/v1.3.1.rst b/doc/source/whatsnew/v1.3.1.rst index eaf514bcd2053..9c17a22bf6d52 100644 --- a/doc/source/whatsnew/v1.3.1.rst +++ b/doc/source/whatsnew/v1.3.1.rst @@ -15,6 +15,7 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ - Pandas could not be built on PyPy (:issue:`42355`) +- :class:`DataFrame` constructed with with an older version of pandas could not be unpickled (:issue:`42345`) - .. --------------------------------------------------------------------------- diff --git a/pandas/_libs/internals.pyx b/pandas/_libs/internals.pyx index 6c1ca3deba047..cfd4695a5335b 100644 --- a/pandas/_libs/internals.pyx +++ b/pandas/_libs/internals.pyx @@ -569,7 +569,12 @@ cdef class BlockManager: public bint _known_consolidated, _is_consolidated public ndarray _blknos, _blklocs - def __cinit__(self, blocks, axes, verify_integrity=True): + def __cinit__(self, blocks=None, axes=None, verify_integrity=True): + # None as defaults for unpickling GH#42345 + if blocks is None: + # This adds 1-2 microseconds to DataFrame(np.array([])) + return + if isinstance(blocks, list): # Backward compat for e.g. pyarrow blocks = tuple(blocks) diff --git a/pandas/tests/io/data/legacy_pickle/1.2.4/empty_frame_v1_2_4-GH#42345.pkl b/pandas/tests/io/data/legacy_pickle/1.2.4/empty_frame_v1_2_4-GH#42345.pkl new file mode 100644 index 0000000000000000000000000000000000000000..255a745dd90218a8ce7c53e54dddcba73a06421d GIT binary patch literal 501 zcmY*W!Ab)$5N)-sSQRN)su#hF)XQSQgEv7%&|(GeOPJkFn_@OCNtRkr(1Y4SZXJKp zpU~MXg*t~YN#2_`^X9Gc{ZlUaaE&pj1WXW*G!Ob3QjTu(8Z6xSe1RwL_=;^;Vd+4l zJ6weimE~H2G(idq23#9-+m~__KiwC1^z?Q}{QdvLgg@pTSad~5L>Rg z%)M|z&7f2_=xRp zIlqdgt0s0j<~e2U;T-3);&%gExDc7V|@t&pSD2C(ZsMM8_Qt~mNN+vmj-7hi-JEf!N{%v literal 0 HcmV?d00001 diff --git a/pandas/tests/io/test_pickle.py b/pandas/tests/io/test_pickle.py index 7cf9d7e9a1925..c4423e6cc4ead 100644 --- a/pandas/tests/io/test_pickle.py +++ b/pandas/tests/io/test_pickle.py @@ -163,9 +163,9 @@ def compare_index_period(result, expected, typ, version): tm.assert_index_equal(result.shift(2), expected.shift(2)) -files = glob.glob( - os.path.join(os.path.dirname(__file__), "data", "legacy_pickle", "*", "*.pickle") -) +here = os.path.dirname(__file__) +legacy_dirname = os.path.join(here, "data", "legacy_pickle") +files = glob.glob(os.path.join(legacy_dirname, "*", "*.pickle")) @pytest.fixture(params=files) @@ -635,3 +635,13 @@ def test_pickle_big_dataframe_compression(protocol, compression): partial(pd.read_pickle, compression=compression), ) tm.assert_frame_equal(df, result) + + +def test_pickle_frame_v124_unpickle_130(): + # GH#42345 DataFrame created in 1.2.x, unpickle in 1.3.x + path = os.path.join(legacy_dirname, "1.2.4", "empty_frame_v1_2_4-GH#42345.pkl") + with open(path, "rb") as fd: + df = pickle.load(fd) + + expected = pd.DataFrame() + tm.assert_frame_equal(df, expected)