X-Git-Url: http://git.tremily.us/?p=hooke.git;a=blobdiff_plain;f=hooke%2Fcurve.py;h=5a32e6d59b8cd2e94902f00e8708d4762cffeb98;hp=75fbf75ce2f394bb9d03dcf39e29ca69bf0419ef;hb=f96f6bdf5bc2bab0a2f527eb87de37e17dc1b96f;hpb=96766f847b6de124dfd1b96eb6e349fdb71a0199 diff --git a/hooke/curve.py b/hooke/curve.py index 75fbf75..5a32e6d 100644 --- a/hooke/curve.py +++ b/hooke/curve.py @@ -163,6 +163,68 @@ class Curve (object): Another important attribute is :attr:`command_stack`, which holds a :class:`~hooke.command_stack.CommandStack` listing the commands that have been applied to the `Curve` since loading. + + The data-type is pickleable, to ensure we can move it between + processes with :class:`multiprocessing.Queue`\s. + + >>> import pickle + >>> import yaml + >>> from .engine import CommandMessage + >>> c = Curve(path='some/path') + + We add a recursive reference to `c` as you would get from + :meth:`hooke.plugin.curve.CurveCommand._add_to_command_stack`. + + >>> c.command_stack.append(CommandMessage('curve info', {'curve':c})) + + >>> s = pickle.dumps(c) + >>> z = pickle.loads(s) + >>> z + + >>> z.command_stack[-1].arguments['curve'] == z + True + >>> print yaml.dump(c) + &id001 !!python/object:hooke.curve.Curve + command_stack: !!python/object/new:hooke.command_stack.CommandStack + listitems: + - !!python/object:hooke.engine.CommandMessage + arguments: + curve: *id001 + command: curve info + data: null + driver: null + info: {} + name: path + path: some/path + + + However, if we try and serialize the command stack first, we run + into `Python issue 1062277`_. + + .. _Python issue 1062277: http://bugs.python.org/issue1062277 + + >>> pickle.dumps(c.command_stack) + Traceback (most recent call last): + ... + assert id(obj) not in self.memo + AssertionError + + YAML still works, though. + + >>> print yaml.dump(c.command_stack) + &id001 !!python/object/new:hooke.command_stack.CommandStack + listitems: + - !!python/object:hooke.engine.CommandMessage + arguments: + curve: !!python/object:hooke.curve.Curve + command_stack: *id001 + data: null + driver: null + info: {} + name: path + path: some/path + command: curve info + """ def __init__(self, path, info=None): #the data dictionary contains: {name of data: list of data sets [{[x], [y]}] @@ -192,38 +254,14 @@ class Curve (object): def __getstate__(self): state = dict(self.__dict__) # make a copy of the attribute dict. - state['info'] = dict(self.info) # make a copy of the info dict too. del(state['_hooke']) - dc = state['command_stack'] - if hasattr(dc, '__getstate__'): - state['command_stack'] = dc.__getstate__() - if state['info'].get('experiment', None) != None: - e = state['info']['experiment'] - assert isinstance(e, experiment.Experiment), type(e) - # HACK? require Experiment classes to be defined in the - # experiment module. - state['info']['experiment'] = e.__class__.__name__ return state def __setstate__(self, state): self.name = self._hooke = None for key,value in state.items(): - if key == 'path': - self.set_path(value) - continue - elif key == 'info': - if 'experiment' not in value: - value['experiment'] = None - elif value['experiment'] != None: - # HACK? require Experiment classes to be defined in the - # experiment module. - cls = getattr(experiment, value['experiment']) - value['experiment'] = cls() - elif key == 'command_stack': - v = CommandStack() - v.__setstate__(value) - value = v setattr(self, key, value) + self.set_path(state.get('path', None)) def set_hooke(self, hooke=None): if hooke != None: