opencobra / optlang

optlang - sympy based mathematical programming language
http://optlang.readthedocs.org/
Apache License 2.0
252 stars 52 forks source link

Gurobi models can not be pickled anymore #232

Closed cdiener closed 3 years ago

cdiener commented 3 years ago

Problem description

Please explain: Pickling and unpickling Gurbi models is broken.

Code Sample

Create a minimal, complete, verifiable example.

In [11]: from cobra.test import create_test_model

In [12]: mod = create_test_model("textbook")

In [13]: mod.solver
Out[13]: <optlang.gurobi_interface.Model at 0x7fc5b1780610>

In [14]: import pickle

In [15]: s = pickle.dumps(mod)

In [16]: m = pickle.loads(s)
Read LP format model from file /tmp/tmp7zsktaxb.lp
Reading time = 0.00 seconds
: 72 rows, 190 columns, 720 nonzeros
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-16-07f4117d4d9e> in <module>
----> 1 m = pickle.loads(s)

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/gurobi_interface.py in __setstate__(self, repr_dict)
    608         #     problem.solve()  # since the start is an optimal solution, nothing will happen here
    609         self.__init__(problem=problem)
--> 610         self.configuration = Configuration.clone(repr_dict['config'], problem=self)  # TODO: make configuration work
    611
    612     def to_lp(self):

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/interface.py in clone(cls, config, problem, **kwargs)
   1000         parameters = {property: getattr(config, property) for property in properties if hasattr(config, property)}
   1001         if hasattr(config, "tolerances"):
-> 1002             parameters["tolerances"] = config.tolerances.to_dict()
   1003         return cls(problem=problem, **parameters)
   1004

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/util.py in to_dict(self)
    313
    314     def to_dict(self):
--> 315         return {key: getattr(self, key) for key in self._functions.keys()}
    316
    317     def __dir__(self):

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/util.py in <dictcomp>(.0)
    313
    314     def to_dict(self):
--> 315         return {key: getattr(self, key) for key in self._functions.keys()}
    316
    317     def __dir__(self):

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/util.py in __getattr__(self, item)
    303     def __getattr__(self, item):
    304         try:
--> 305             return self._functions[item][0]()
    306         except KeyError:
    307             raise AttributeError(item + " is not an available tolerance parameter with this solver")

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/gurobi_interface.py in _get_feasibility(self)
    487
    488     def _get_feasibility(self):
--> 489         return getattr(self.problem.problem.params, "FeasibilityTol")
    490
    491     def _set_feasibility(self, value):

AttributeError: 'NoneType' object has no attribute 'problem'
AttributeError                            Traceback (most recent call last)
<ipython-input-16-07f4117d4d9e> in <module>
----> 1 m = pickle.loads(s)

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/gurobi_interface.py in __setstate__(self, repr_dict)
    608         #     problem.solve()  # since the start is an optimal solution, nothing will happen here
    609         self.__init__(problem=problem)
--> 610         self.configuration = Configuration.clone(repr_dict['config'], problem=self)  # TODO: make configuration work
    611
    612     def to_lp(self):

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/interface.py in clone(cls, config, problem, **kwargs)
   1000         parameters = {property: getattr(config, property) for property in properties if hasattr(config, property)}
   1001         if hasattr(config, "tolerances"):
-> 1002             parameters["tolerances"] = config.tolerances.to_dict()
   1003         return cls(problem=problem, **parameters)
   1004

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/util.py in to_dict(self)
    313
    314     def to_dict(self):
--> 315         return {key: getattr(self, key) for key in self._functions.keys()}
    316
    317     def __dir__(self):

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/util.py in <dictcomp>(.0)
    313
    314     def to_dict(self):
--> 315         return {key: getattr(self, key) for key in self._functions.keys()}
    316
    317     def __dir__(self):

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/util.py in __getattr__(self, item)
    303     def __getattr__(self, item):
    304         try:
--> 305             return self._functions[item][0]()
    306         except KeyError:
    307             raise AttributeError(item + " is not an available tolerance parameter with this solver")

~/miniconda3/envs/micom/lib/python3.7/site-packages/optlang/gurobi_interface.py in _get_feasibility(self)
    487
    488     def _get_feasibility(self):
--> 489         return getattr(self.problem.problem.params, "FeasibilityTol")
    490
    491     def _set_feasibility(self, value):

AttributeError: 'NoneType' object has no attribute 'problem'

Context

This was using optlang 1.5.0, but optlang has no function show_versions ....

``` ```