I need to pickle a Python3 object to a string which I want to unpickle from an environmental variable in a Travis CI build. The problem is that I can\'t seem to find a way t
pickle.dumps() produces a bytes object. Expecting these arbitrary bytes to be valid UTF-8 text (the assumption you are making by trying to decode it to a string from UTF-8) is pretty optimistic. It'd be a coincidence if it worked!
One solution is to use the older pickling protocol that uses entirely ASCII characters. This still comes out as bytes, but since it is ASCII-only it can be decoded to a string without stress:
pickled = pickle.dumps(obj, 0).decode()
You could also use some other encoding method to encode a binary-pickled object to text, such as base64:
import codecs
pickled = codecs.encode(pickle.dumps(obj), "base64").decode()
Decoding would then be:
unpickled = pickle.loads(codecs.decode(pickled.encode(), "base64"))
Using pickle with protocol 0 seems to result in shorter strings than base64-encoding binary pickles (and abarnert's suggestion of hex-encoding is going to be even larger than base64), but I haven't tested it rigorously or anything. Test it with your data and see.