1

I am trying to convert a Python 2 code into Python 3. I used the pickle.loads function in Python 2.7, which according to its documentation does the following (https://docs.python.org/2.7/library/pickle.html):

pickle.loads(string)
Read a pickled object hierarchy from a string. Characters in the 
string past the pickled object’s representation are ignored.

However its behavior changes in Python 3 (https://docs.python.org/3/library/pickle.html):

pickle.loads(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict")
Read a pickled object hierarchy from a bytes object and return the 
reconstituted object hierarchy specified therein.

In the database, I have a string x which was the output of pickle.dumps(obj) performed in Python 2. I want to retrieve obj in Python 3. When I do pickle.loads(x), I receive the following error:

a bytes-like object is required, not 'str'

Changing pickle.loads(x) into pickle.loads(bytes(x, 'utf-8')) instead gives the following error:

invalid load key, '\x5c'.

How can I obtain obj from x in Python 3?

6
  • If you're trying to read a pickle created by Python 2 into Python 3, you need to set the right protocol: docs.python.org/3/library/pickle.html#data-stream-format Commented Apr 22, 2019 at 9:30
  • This article outlines the entire process by which one would do this, including gotchas. Commented Apr 22, 2019 at 9:32
  • @jonrsharpe according to its documentation: The protocol version of the pickle is detected automatically, so no protocol argument is needed. Is it still necessary to explicitly set the protocol when I call python.loads? Commented Apr 22, 2019 at 9:33
  • @alec_a The article talks mostly about pickle.load instead of pickle.loads. I couldn't resolve my problem by trying a similar fix for pickle.loads. Commented Apr 22, 2019 at 9:34
  • blog.yannisassael.com/2016/03/open-python-2-pickle-python-3 Commented Apr 22, 2019 at 9:35

1 Answer 1

2

Change pickle.loads(x) to pickle.loads(bytes(x, 'latin-1')).

Change pickle.dumps(o) to str(pickle.dumps(o, protocol=0), 'latin-1').

Sign up to request clarification or add additional context in comments.

1 Comment

Or leveraging the internal of python, passing the encode arg would do it. pickle.load(x, encoding='latin1') Checkout this answer stackoverflow.com/questions/28218466/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.