Question: Is there a way to tell Pandas to use a specific pickle protocol (e.g. 4) when writing an HDF5 file? Here is the situation (much simplified):  Client A is using python=3.8.1 (as well as pandas=1.0.0 and pytables=3.6.1). A writes some DataFrame using df.to_hdf(file, key). Client B is using python=3.7.1 (and, as it happened, pandas=0.25.1 and pytables=3.5.2 --but that's irrelevant). B tries to read the data written by A using pd.read_hdf(file, key), and fails with ValueError: unsupported pickle protocol: 5.  Mind you, this doesn't happen with a purely numerical DataFrame (e.g. pd.DataFrame(np.random.normal(size=(10,10))). So here is a reproducible example: (base) $ conda activate py38 (py38) $ python Python 3.8.1 (default, Jan 8 2020, 22:29:32) [GCC 7.3.0] :: Anaconda, Inc. on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pandas as pd >>> df = pd.DataFrame(['hello', 'world'])) >>> df.to_hdf('foo', 'x') >>> exit() (py38) $ conda deactivate (base) $ python Python 3.7.4 (default, Aug 13 2019, 20:35:49) [GCC 7.3.0] :: Anaconda, Inc. on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pandas as pd >>> df = pd.read_hdf('foo', 'x') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 407, in read_hdf return store.select(key, auto_close=auto_close, **kwargs) File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 782, in select return it.get_result() File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 1639, in get_result results = self.func(self.start, self.stop, where) File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 766, in func return s.read(start=_start, stop=_stop, where=_where, columns=columns) File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 3206, in read "block{idx}_values".format(idx=i), start=_start, stop=_stop File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 2737, in read_array ret = node[0][start:stop] File "/opt/anaconda3/lib/python3.7/site-packages/tables/vlarray.py", line 681, in __getitem__ return self.read(start, stop, step)[0] File "/opt/anaconda3/lib/python3.7/site-packages/tables/vlarray.py", line 825, in read outlistarr = [atom.fromarray(arr) for arr in listarr] File "/opt/anaconda3/lib/python3.7/site-packages/tables/vlarray.py", line 825, in <listcomp> outlistarr = [atom.fromarray(arr) for arr in listarr] File "/opt/anaconda3/lib/python3.7/site-packages/tables/atom.py", line 1227, in fromarray return six.moves.cPickle.loads(array.tostring()) ValueError: unsupported pickle protocol: 5 >>>  Note: I tried also reading using pandas=1.0.0 (and pytables=3.6.1) in python=3.7.4. That fails too, so I believe it is simply the Python version (3.8 writer vs 3.7 reader) that causes the problem. This makes sense since pickle protocol 5 was introduced as PEP-574 for Python 3.8.

Answer: Update: I was wrong to assume this was not possible. In fact, based on the excellent "monkey-patch" suggestion of @PiotrJurkiewicz, here is a simple context manager that lets us temporarily change the highest pickle protocol. It:  Hides the monkey-patching, and Has no side-effect outside of the context; it can be used at any time, whether pickle was previously imported or not, before or after pandas, no matter.  Here is the code (e.g. in a file pickle_prot.py): import importlib import pickle class PickleProtocol: def __init__(self, level): self.previous = pickle.HIGHEST_PROTOCOL self.level = level def __enter__(self): importlib.reload(pickle) pickle.HIGHEST_PROTOCOL = self.level def __exit__(self, *exc): importlib.reload(pickle) pickle.HIGHEST_PROTOCOL = self.previous def pickle_protocol(level): return PickleProtocol(level)  Usage example in a writer: import pandas as pd from pickle_prot import pickle_protocol pd.DataFrame(['hello', 'world']).to_hdf('foo_0.h5', 'x') with pickle_protocol(4): pd.DataFrame(['hello', 'world']).to_hdf('foo_1.h5', 'x') pd.DataFrame(['hello', 'world']).to_hdf('foo_2.h5', 'x')  And, using a simple test reader: import pandas as pd from glob import glob for filename in sorted(glob('foo_*.h5')): try: df = pd.read_hdf(filename, 'x') print(f'could read {filename}') except Exception as e: print(f'failed on {filename}: {e}')  Now, trying to read in py37 after having written in py38, we get: failed on foo_0.h5: unsupported pickle protocol: 5 could read foo_1.h5 failed on foo_2.h5: unsupported pickle protocol: 5  But, using the same version (37 or 38) to read and write, we of course get no exception. Note: the issue 33087 is still on Pandas issue tracker.