tBuLi / symfit

Symbolic Fitting; fitting as it should be.
http://symfit.readthedocs.org
MIT License
235 stars 19 forks source link

pickles #100

Closed Jhsmit closed 5 years ago

Jhsmit commented 7 years ago

symfit Fit objects can't be pickled (or loaded).

In Python 3.5.2 a RecursionError is raised when attempting to load a pickled object:

Traceback (most recent call last):
  File "C:/Users/Smit/PycharmProjects/CellCoordinates/testmeuk/test_symfit_pickle.py", line 25, in <module>
    fit = pickle.load(fid)
  File "C:\Miniconda3\envs\py_main\lib\site-packages\symfit\core\fit.py", line 90, in __getattr__
    return self.__popt[name]
RecursionError: maximum recursion depth exceeded while calling a Python object

Same error when using dill in python 3.

In Python 2. 7 a RecursionError is raised when attempting to dump an object:

Traceback (most recent call last):
  File "C:/Users/Smit/PycharmProjects/CellCoordinates/testmeuk/test_symfit_pickle.py", line 21, in <module>
    pickle.dump(fit, fid)
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 1376, in dump
    Pickler(file, protocol).dump(obj)
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 224, in dump
    self.save(obj)
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 425, in save_reduce
    save(state)
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 655, in save_dict
    self._batch_setitems(obj.iteritems())
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 669, in _batch_setitems
    save(v)
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 425, in save_reduce
    save(state)
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 655, in save_dict
    self._batch_setitems(obj.iteritems())
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 669, in _batch_setitems
    save(v)
  File "C:\Miniconda3\envs\py27_cp\lib\pickle.py", line 306, in save
    rv = reduce(self.proto)
  File "C:\Miniconda3\envs\py27_cp\lib\copy_reg.py", line 77, in _reduce_ex
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
pckroon commented 7 years ago

I can't reproduce the infinite recursion error. But I can make the last one. AFAICS the problem lies with Model, not Fit.

model = Model(...)
ode_model = ODEModel(...)

with open('/tmp/symfit.pickle', 'wb') as jar:
    pickle.dump(model, jar)
with open('/tmp/symfit.pickle', 'rb') as jar:
    pickle.load(jar)
with open('/tmp/symfit_ode.pickle', 'wb') as ode_jar:
    pickle.dump(ode_model, ode_jar)
with open('/tmp/symfit_ode.pickle', 'rb') as ode_jar:
    pickle.load(ode_jar)

With an ODEModel: Python 2.7: a class that defines slots without defining getstate cannot be pickled Python 3.5: No error.

With a normal Model: Python 2.7: a class that defines slots without defining getstate cannot be pickled Python 3.5: No errors.

However. It's a bit of a Heisenbug:

model = Model(...)
ode_model = ODEModel(...)

model(...)
ode_model(...)

with open('/tmp/symfit.pickle', 'wb') as jar:
    pickle.dump(model, jar)
with open('/tmp/symfit.pickle', 'rb') as jar:
    pickle.load(jar)
with open('/tmp/symfit_ode.pickle', 'wb') as ode_jar:
    pickle.dump(ode_model, ode_jar)
with open('/tmp/symfit_ode.pickle', 'rb') as ode_jar:
    pickle.load(ode_jar)

With an ODEModel: Python 2.7: a class that defines slots without defining getstate cannot be pickled Python 3.5: Can't pickle <function at 0x7fc718098598>: attribute lookup on numpy failed

With a normal Model: Python 2.7: a class that defines slots without defining getstate cannot be pickled Python 3.5: No errors.

tBuLi commented 5 years ago

Pcikle support has by now been added, closing.