The code below causes a
AttributeError: 'Event' object has no attribute 'name'
It seems like the entries of `Machine.events` are not available during `__setstate__`. However, the behaviour depends on the Python version.
For Python 3.6.4 it's always the 'first' (as in it's always 'to_A' which has been added first) element in `Machine.events` that is incomplete. For Python 3.4.8 and 3.5.5 it looks like a racing condition since sometimes there is no error, sometimes its the first or the second element which is incomplete.
Letting `Machine` serve as its own model and pickling that does work for all three versions.
Tested on MacOS High Sierra.
```
import pickle
from functools import partial
class Event:
def __init__(self, name, machine):
self.name = name
self.machine = machine
def trigger(self):
pass
class Machine:
def __init__(self, model, states):
self.events = {}
self.model = model if model != 'self' else self
for state in states:
trigger = 'to_%s' % state
self.events[trigger] = Event(trigger, self)
trig_func = partial(self.events[trigger].trigger)
setattr(self.model, trigger, trig_func)
def __getstate__(self):
return self.__dict__
def __setstate__(self, state):
self.__dict__.update(state)
print(self.events['to_B'].name)
print(self.events['to_A'].name)
class Model:
def __init__(self):
self.machine = Machine(self, states=['A', 'B'])
model = Model()
dump = pickle.dumps(model)
model2 = pickle.loads(dump)
```
|