Skip to content

Commit

Permalink
fix: enable pickling an model with context (#463)
Browse files Browse the repository at this point in the history
Contexts cannot (and shouldn't) be saved, but one may want to save a
model object that has a context. This was possible as partial functions
cannot be pickled. Fix this by deleting the context in model's
__getstate__. Adjust the IO test to write the model within a context.
  • Loading branch information
hredestig committed Mar 22, 2017
1 parent feb9da1 commit 8a574be
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
13 changes: 12 additions & 1 deletion cobra/core/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ class Model(Object):
"""

def __setstate__(self, state):
"""Make sure all cobra.Objects in the model point to the model"""
"""Make sure all cobra.Objects in the model point to the model.
"""
self.__dict__.update(state)
for y in ['reactions', 'genes', 'metabolites']:
for x in getattr(self, y):
Expand All @@ -64,6 +65,16 @@ def __setstate__(self, state):
if not hasattr(self, "name"):
self.name = None

def __getstate__(self):
"""Get state for serialization.
Ensures that the context stack is cleared prior to serialization,
since partial functions cannot be pickled reliably.
"""
odict = self.__dict__.copy()
odict['_contexts'] = []
return odict

def __init__(self, id_or_model=None, name=None):
if isinstance(id_or_model, Model):
Object.__init__(self, name=name)
Expand Down
5 changes: 4 additions & 1 deletion cobra/test/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ def io_trial(request, data_directory):
request.param.test_file))
test_output_filename = join(gettempdir(),
split(request.param.test_file)[-1])
request.param.write_function(test_model, test_output_filename)
# test writing the model within a context with a non-empty stack
with test_model:
test_model.objective = test_model.objective
request.param.write_function(test_model, test_output_filename)
reread_model = request.param.read_function(test_output_filename)
unlink(test_output_filename)
return request.param.name, reference_model, test_model, reread_model
Expand Down

0 comments on commit 8a574be

Please sign in to comment.