Unpickling classes from Python 3 to Python 2

If a Python 3 class is pickled using Protocol 2, it should work in Python 2, but unfortunately this fails because the names of some classes have changed.

Suppose we have code called as follows.

Sender

pickle.dumps(obj,2)

Receiver

pickle.loads(atom)

To give a specific case, if obj={}, then the indicated error:

ImportError: no module named builtins

This is because Python 2 uses it instead __builtin__.

Question is the best way to fix this problem.

+5
source share
1 answer

This issue is Python issue 3675 . This bug is actually fixed in Python 3.11.

:

from lib2to3.fixes.fix_imports import MAPPING

MAPPING Python 2 Python 3. .

REVERSE_MAPPING={}
for key,val in MAPPING.items():
    REVERSE_MAPPING[val]=key

Unpickler

class Python_3_Unpickler(pickle.Unpickler):
    """Class for pickling objects from Python 3"""
    def find_class(self,module,name):
        if module in REVERSE_MAPPING:
            module=REVERSE_MAPPING[module]
        __import__(module)
        mod = sys.modules[module]
        klass = getattr(mod, name)
        return klass

def loads(str):
    file = pickle.StringIO(str)
    return Python_3_Unpickler(file).load()  

pickle.loads.

.

+13

All Articles