Skip to content

CLN: PY3 Remove cPickle #25956

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 4 commits into from
Apr 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions pandas/compat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,11 @@
# always writeable
from StringIO import StringIO
BytesIO = StringIO
import cPickle
import httplib
except ImportError:
import builtins
from io import StringIO, BytesIO
cStringIO = StringIO
import pickle as cPickle
import http.client as httplib

from pandas.compat.chainmap import DeepChainMap
Expand Down
27 changes: 7 additions & 20 deletions pandas/compat/pickle_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import sys

import pandas # noqa
from pandas import Index, compat
from pandas import Index


def load_reduce(self):
Expand Down Expand Up @@ -138,27 +138,14 @@ def load_reduce(self):
# our Unpickler sub-class to override methods and some dispatcher
# functions for compat

if compat.PY3:
class Unpickler(pkl._Unpickler):
class Unpickler(pkl._Unpickler):

def find_class(self, module, name):
# override superclass
key = (module, name)
module, name = _class_locations_map.get(key, key)
return super(Unpickler, self).find_class(module, name)
def find_class(self, module, name):
# override superclass
key = (module, name)
module, name = _class_locations_map.get(key, key)
return super(Unpickler, self).find_class(module, name)

else:

class Unpickler(pkl.Unpickler):

def find_class(self, module, name):
# override superclass
key = (module, name)
module, name = _class_locations_map.get(key, key)
__import__(module)
mod = sys.modules[module]
klass = getattr(mod, name)
return klass

Unpickler.dispatch = copy.copy(Unpickler.dispatch)
Unpickler.dispatch[pkl.REDUCE[0]] = load_reduce
Expand Down
6 changes: 3 additions & 3 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import gc
import json
import operator
import pickle
from textwrap import dedent
import warnings
import weakref
Expand All @@ -15,8 +16,7 @@

from pandas._libs import Timestamp, iNaT, properties
import pandas.compat as compat
from pandas.compat import (
cPickle as pkl, isidentifier, lrange, lzip, set_function_name, to_str)
from pandas.compat import isidentifier, lrange, lzip, set_function_name, to_str
from pandas.compat.numpy import function as nv
from pandas.errors import AbstractMethodError
from pandas.util._decorators import (
Expand Down Expand Up @@ -2564,7 +2564,7 @@ def to_sql(self, name, con, schema=None, if_exists='fail', index=True,
dtype=dtype, method=method)

def to_pickle(self, path, compression='infer',
protocol=pkl.HIGHEST_PROTOCOL):
protocol=pickle.HIGHEST_PROTOCOL):
"""
Pickle (serialize) object to file.

Expand Down
18 changes: 10 additions & 8 deletions pandas/io/pickle.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
""" pickle compat """
import pickle
import warnings

from numpy.lib.format import read_array

from pandas.compat import BytesIO, cPickle as pkl, pickle_compat as pc
from pandas.compat import BytesIO, pickle_compat as pc

from pandas.io.common import _get_handle, _stringify_path


def to_pickle(obj, path, compression='infer', protocol=pkl.HIGHEST_PROTOCOL):
def to_pickle(obj, path, compression='infer',
protocol=pickle.HIGHEST_PROTOCOL):
"""
Pickle (serialize) object to file.

Expand Down Expand Up @@ -71,9 +73,9 @@ def to_pickle(obj, path, compression='infer', protocol=pkl.HIGHEST_PROTOCOL):
compression=compression,
is_text=False)
if protocol < 0:
protocol = pkl.HIGHEST_PROTOCOL
protocol = pickle.HIGHEST_PROTOCOL
try:
f.write(pkl.dumps(obj, protocol=protocol))
f.write(pickle.dumps(obj, protocol=protocol))
finally:
f.close()
for _f in fh:
Expand Down Expand Up @@ -140,15 +142,15 @@ def read_pickle(path, compression='infer'):
path = _stringify_path(path)
f, fh = _get_handle(path, 'rb', compression=compression, is_text=False)

# 1) try with cPickle
# 2) try with the compat pickle to handle subclass changes
# 3) pass encoding only if its not None as py2 doesn't handle the param
# 1) try standard libary Pickle
# 2) try pickle_compat (older pandas version) to handle subclass changes
# 3) try pickle_compat with latin1 encoding

try:
with warnings.catch_warnings(record=True):
# We want to silence any warnings about, e.g. moved modules.
warnings.simplefilter("ignore", Warning)
return pkl.load(f)
return pickle.load(f)
except Exception: # noqa: E722
try:
return pc.load(f, encoding=None)
Expand Down
6 changes: 1 addition & 5 deletions pandas/tests/io/generate_legacy_storage_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from datetime import timedelta
from distutils.version import LooseVersion
import os
import pickle
import platform as pl
import sys

Expand Down Expand Up @@ -285,11 +286,6 @@ def platform_name():
def write_legacy_pickles(output_dir):

# make sure we are < 0.13 compat (in py3)
try:
from pandas.compat import cPickle as pickle # noqa
except ImportError:
import pickle

version = pandas.__version__

print("This script generates a storage file for the current arch, system, "
Expand Down
28 changes: 4 additions & 24 deletions pandas/tests/io/test_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import gzip
import lzma
import os
import pickle
import shutil
from warnings import catch_warnings, simplefilter
import zipfile
Expand Down Expand Up @@ -217,37 +218,20 @@ def test_pickles(current_pickle_data, legacy_pickle):

def test_round_trip_current(current_pickle_data):

try:
import cPickle as c_pickle

def c_pickler(obj, path):
with open(path, 'wb') as fh:
c_pickle.dump(obj, fh, protocol=-1)

def c_unpickler(path):
with open(path, 'rb') as fh:
fh.seek(0)
return c_pickle.load(fh)
except ImportError:
c_pickler = None
c_unpickler = None

import pickle as python_pickle

def python_pickler(obj, path):
with open(path, 'wb') as fh:
python_pickle.dump(obj, fh, protocol=-1)
pickle.dump(obj, fh, protocol=-1)

def python_unpickler(path):
with open(path, 'rb') as fh:
fh.seek(0)
return python_pickle.load(fh)
return pickle.load(fh)

data = current_pickle_data
for typ, dv in data.items():
for dt, expected in dv.items():

for writer in [pd.to_pickle, c_pickler, python_pickler]:
for writer in [pd.to_pickle, python_pickler]:
if writer is None:
continue

Expand All @@ -260,10 +244,6 @@ def python_unpickler(path):
result = pd.read_pickle(path)
compare_element(result, expected, typ)

if c_unpickler is not None:
result = c_unpickler(path)
compare_element(result, expected, typ)

result = python_unpickler(path)
compare_element(result, expected, typ)

Expand Down