1

I am migrating a large piece of software from python 2.7 to python 3.7

For back-testing purposes, I need to be able to read old (2.7) pickles in new (3.7) python, and vice versa.

I can read old pickles in new python.

I want to also be able to read new pickles in old python.

I found this answer, but it is not good for me, as it requires me to change the pickle.

Is there a way to read a python 3 pickle in python 2 without changing the pickle?

Gulzar
  • 23,452
  • 27
  • 113
  • 201
  • 2
    Hope you don't mind me asking, but why do you even care about the 3 to 2 direction? 2 has reached EOL – DeepSpace Jan 07 '20 at 14:08
  • @DeepSpace I also asked the same question, It didn't seem to help. The company wants to be able to run old versions of the software against new ones, and be able to compare. Some parts of the software may produce pickles, and we may need to inject them into the software running in python 2 for testing. – Gulzar Jan 07 '20 at 14:13
  • 2
    This is a question of which `pickle` protocol is being used, more than which version of Python you are using, though the two are related. Python 2 `pickle` supports protocols 0, 1, and 2, while protocols 3, 4, and 5 have been introduced since the release of Python 3. I'm not sure you have any choice but to explicitly use protocol 2 in your Python 3 code if you need to ensure backwards compatibility. – chepner Jan 07 '20 at 14:32
  • See [this question](https://stackoverflow.com/q/23582489/1126841), especially [this answer to the question](https://stackoverflow.com/a/46213977/1126841). – chepner Jan 07 '20 at 14:34
  • @chepner this again suggests to change the pickle, or tells me it is impossible. since nothing is impossible, this doesn't solve the problem. – Gulzar Jan 08 '20 at 08:33
  • @Gulzar I am having this exact same problem! Have you found any solution to it outside of outright modifying the original pickle file? – Anonymous Person Jan 30 '20 at 14:00
  • @AnonymousPerson see answer – Gulzar Jan 30 '20 at 14:08

1 Answers1

0

This is the best solution I could find:

Since I am able to change the new software, but not the old one, every time I create a pickle which has to be read by the old software, I do

def create_old_pickle(new_pickle):
    loaded = pickle.loads(new_pickle)
    repickled = pickle.dumps(loaded, protocol=2)
    return repickled

This creates old pickles in new python.

Thus old software API remains the same.

You may notice unicode->bytes problems, but that's something else.

Gulzar
  • 23,452
  • 27
  • 113
  • 201