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 2 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
14 changes: 8 additions & 6 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
# 1) try with Pickle
# 2) try with the compat pickle to handle subclass changes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor but I suppose we don't need a three step comment here anymore

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically there's still a 3 step process, "compat pickle" in this case refers to compatibility with older versions of pandas and not PY2/3 compat.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will clarify this comment though.

# 3) pass encoding only if its not None as py2 doesn't handle the param

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
5 changes: 1 addition & 4 deletions pandas/tests/io/generate_legacy_storage_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,7 @@ 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
import pickle

version = pandas.__version__

Expand Down
21 changes: 1 addition & 20 deletions pandas/tests/io/test_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,21 +217,6 @@ 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):
Expand All @@ -247,7 +232,7 @@ def python_unpickler(path):
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 +245,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