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

Fix #431 #434

Merged
merged 1 commit into from Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGES.rst
@@ -1,3 +1,9 @@
v3.0.2
======
* Properly raise warning if a custom pickling handler returns None. (#433)
* Fix issue with serialization of certain sklearn objects breaking when
the numpy handler was enabled. (#431) (+434)

v3.0.1
======
* Remove accidental pin of setuptools to versions below 59. This allows
Expand Down
3 changes: 3 additions & 0 deletions jsonpickle/ext/numpy.py
Expand Up @@ -324,6 +324,9 @@ def restore(self, data):
else:
# decode array view, which references the data of another array
base = self.context.restore(base, reset=False)
if not isinstance(base, np.ndarray):
# the object is probably a nested list
base = np.array(base)
assert (
base.flags.forc
), "Current implementation assumes base is C or F contiguous"
Expand Down
19 changes: 19 additions & 0 deletions tests/sklearn_test.py
Expand Up @@ -4,6 +4,8 @@

try:
import numpy as np
import sklearn.datasets
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
except ImportError:
pytest.skip('sklearn is not available', allow_module_level=True)
Expand Down Expand Up @@ -53,5 +55,22 @@ def test_decision_tree():
assert actual.get_depth() == classifier.get_depth()


def test_nested_array_serialization():
iris = sklearn.datasets.load_iris()
X = iris.data[:, :2]
y = (iris.target != 0) * 1

pipe = LogisticRegression(solver="lbfgs")
pipe.fit(X, y)
res = pipe.predict(X)

# Try serializing/deserializing.
# Pipe is a LogisticRegression object that contains a nested array
js = jsonpickle.dumps(pipe)
pipe2 = jsonpickle.loads(js)
# coef_ only appears on an instance that has already been fit to something
assert np.all(pipe.coef_ == pipe2.coef_)


if __name__ == '__main__':
pytest.main([__file__])