Repository: joblib/joblib

Issue:
load fails when dump use pickle.HIGHEST_PROTOCOL in Python 3
in master branch a96878e (version 0.10.0.dev0), the following code gives `KeyError`

```py
import pickle
import numpy as np
import joblib

a = np.zeros((1, 235), np.uint32)
joblib.dump(a, 'tmp.jl', protocol=pickle.HIGHEST_PROTOCOL)
joblib.load('tmp.jl')
```

That is: joblib seems do not support load data which saved with `pickle.HIGHEST_PROTOCOL`

Discussion:
aabadie: I pushed an update commit (1c7763e) that ensures the numpy array wrapper is written in a dedicated frame in the pickle byte stream. I think it's cleaner.
aabadie: @lesteve, comments addressed.
aabadie: @lesteve, I reverted to the initial solution. 
lesteve: LGTM, merging, great job!

Patch:
diff --git a/joblib/numpy_pickle.py b/joblib/numpy_pickle.py
index 0cb616d..f029582 100644
--- a/joblib/numpy_pickle.py
+++ b/joblib/numpy_pickle.py
@@ -265,6 +265,14 @@ class NumpyPickler(Pickler):
             wrapper = self._create_array_wrapper(obj)
             Pickler.save(self, wrapper)
 
+            # A framer was introduced with pickle protocol 4 and we want to
+            # ensure the wrapper object is written before the numpy array
+            # buffer in the pickle file.
+            # See https://www.python.org/dev/peps/pep-3154/#framing to get
+            # more information on the framer behavior.
+            if self.proto >= 4:
+                self.framer.commit_frame(force=True)
+
             # And then array bytes are written right after the wrapper.
             wrapper.write_array(obj, self)
             return


Test patch:
diff --git a/joblib/test/test_numpy_pickle.py b/joblib/test/test_numpy_pickle.py
index 321a428..19a5e95 100644
--- a/joblib/test/test_numpy_pickle.py
+++ b/joblib/test/test_numpy_pickle.py
@@ -13,6 +13,7 @@ import warnings
 import nose
 import gzip
 import zlib
+import pickle
 from contextlib import closing
 
 from joblib.test.common import np, with_numpy
@@ -821,3 +822,18 @@ def test_non_contiguous_array_pickling():
         array_reloaded = numpy_pickle.load(filename)
         np.testing.assert_array_equal(array_reloaded, array)
         os.remove(filename)
+
+
+@with_numpy
+def test_pickle_highest_protocol():
+    # ensure persistence of a numpy array is valid even when using
+    # the pickle HIGHEST_PROTOCOL.
+    # see https://github.com/joblib/joblib/issues/362
+
+    filename = env['filename'] + str(random.randint(0, 1000))
+    test_array = np.zeros(10)
+
+    numpy_pickle.dump(test_array, filename, protocol=pickle.HIGHEST_PROTOCOL)
+    array_reloaded = numpy_pickle.load(filename)
+
+    np.testing.assert_array_equal(array_reloaded, test_array)