Skip to content
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

Most Menpo Python 2 pickles cannot be loaded into Python 3 #722

Closed
jabooth opened this issue Aug 8, 2016 · 3 comments
Closed

Most Menpo Python 2 pickles cannot be loaded into Python 3 #722

jabooth opened this issue Aug 8, 2016 · 3 comments

Comments

@jabooth
Copy link
Member

jabooth commented Aug 8, 2016

This is because our pathlib.Path objects contain strings which need to marshalled to unicode on loading into Python 3.

The default for Python 3 loading a Python 2 pickle is to only decode valid ASCII characters to strings. If you come across an invalid character, you get this:

/.../lib/python3.5/site-packages/menpo/io/input/base.py in 
_import(filepath, extensions_map, landmark_resolver, landmark_ext_map, 
        landmark_attach_func, asset, importer_kwargs)
    802     if importer_kwargs is None:
    803         importer_kwargs = {}
--> 804     built_objects = importer_callable(path, asset=asset, **importer_kwargs)
    805 
    806     # landmarks are iterable so check for list precisely

/.../lib/python3.5/site-packages/menpo/io/input/pickle.py in
pickle_importer(filepath, asset, **kwargs)
     25     """
     26     with open(str(filepath), 'rb') as f:
---> 27         x = pickle.load(f)
     28     return x
     29 

UnicodeDecodeError: 'ascii' codec can't decode byte 0x81 in position 2: 
ordinal not in range(128)

A solution to this is to change the import encoding to latin1 in Python 3:

import pickle

with open('a.pkl', 'rb') as f:
    d = pickle.load(f, encoding='latin1')

However this is a bold change to make so I'm making this issue to think through any possible consequences.

If we decided to do this, note that we would need a Python version check to add it, as pickle.load() in Python 2.7 does not take any kwargs.

We should also bear in mind that we may head towards Python 3 only support (#721). This issue is both an example of the kind of burden we could rid ourselves of by moving sooner, and potentially something that isn't worth solving if a commitment to Python 3 is on the horizon (i.e. - rather than muddy the waters our official stance can be Python 2/3 pickles are incompatible and we can just remove this confusion down the line by some point dropping Python 2).

@jabooth
Copy link
Member Author

jabooth commented Aug 9, 2016

A worrying reason why not to set the default to 'latin1':

numpy/numpy#4879

pv (numpy member)
Using encoding='latin1' probably works in many cases, but e.g. Python 2's datetime objects are not pickleable on Py3 with it.

@patricksnape
Copy link
Contributor

Crikey.

@patricksnape
Copy link
Contributor

Work around added by #723

nfahlgren added a commit to fabid/plantcv that referenced this issue Dec 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants