From 07d84098df5efe5db97461a0568c813f634ea117 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Sat, 21 Aug 2010 14:37:20 -0400 Subject: [PATCH] Added hooke.util.yaml fixing YAML/NumPy type issues (by dropping data). --- hooke/__init__.py | 1 + hooke/curve.py | 31 ++++++++++++++---------- hooke/playlist.py | 18 -------------- hooke/util/yaml.py | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 31 deletions(-) create mode 100644 hooke/util/yaml.py diff --git a/hooke/__init__.py b/hooke/__init__.py index 30abbd1..a220d8b 100644 --- a/hooke/__init__.py +++ b/hooke/__init__.py @@ -33,6 +33,7 @@ except ImportError, e: logging.warn('could not load LICENSE from hooke.license') __license__ = 'All rights reserved.' +from .util import yaml # extend YAML to parse Hooke-specific items. __version__ = (1, 0, 0, 'alpha', None, 'Ninken') """Version tuple:: diff --git a/hooke/curve.py b/hooke/curve.py index 5a32e6d..12ac5eb 100644 --- a/hooke/curve.py +++ b/hooke/curve.py @@ -87,6 +87,14 @@ class Data (numpy.ndarray): [ 20., 21.]]) >>> z.info {'columns': ['distance (m)', 'force (N)']} + + The data-type is also YAMLable (see :mod:`hooke.util.yaml`). + + >>> import yaml + >>> print yaml.dump(d) + null + ... + """ def __new__(subtype, shape, dtype=numpy.float, buffer=None, offset=0, strides=None, order=None, info=None): @@ -183,7 +191,7 @@ class Curve (object): >>> z.command_stack[-1].arguments['curve'] == z True - >>> print yaml.dump(c) + >>> print yaml.dump(c) # doctest: +REPORT_UDIFF &id001 !!python/object:hooke.curve.Curve command_stack: !!python/object/new:hooke.command_stack.CommandStack listitems: @@ -211,7 +219,7 @@ class Curve (object): YAML still works, though. - >>> print yaml.dump(c.command_stack) + >>> print yaml.dump(c.command_stack) # doctest: +REPORT_UDIFF &id001 !!python/object/new:hooke.command_stack.CommandStack listitems: - !!python/object:hooke.engine.CommandMessage @@ -227,16 +235,7 @@ class Curve (object): """ def __init__(self, path, info=None): - #the data dictionary contains: {name of data: list of data sets [{[x], [y]}] - self.name = None - self.set_path(path) - self.driver = None - self.data = None - if info == None: - info = {} - self.info = info - self.command_stack = CommandStack() - self._hooke = None # Hooke instance for Curve.load() + self.__setstate__({'path':path, 'info':info}) def __str__(self): return str(self.__unicode__()) @@ -258,9 +257,15 @@ class Curve (object): return state def __setstate__(self, state): - self.name = self._hooke = None + # .data contains: {name of data: list of data sets [{[x], [y]}] + # ._hooke contains a Hooke instance for Curve.load() + self.name = self.driver = self.data = self._hooke = None + self.info = {} + self.command_stack = CommandStack() for key,value in state.items(): setattr(self, key, value) + if self.info == None: + self.info = {} self.set_path(state.get('path', None)) def set_hooke(self, hooke=None): diff --git a/hooke/playlist.py b/hooke/playlist.py index b996a5f..3380bfc 100644 --- a/hooke/playlist.py +++ b/hooke/playlist.py @@ -27,24 +27,6 @@ import os import os.path import types -if False: # YAML dump debugging code - """To help isolate data types etc. that give YAML problems. - - This is usually caused by external C modules (e.g. numpy) that - define new types (e.g. numpy.dtype) which YAML cannot inspect. - """ - import yaml.representer - import sys - def ignore_aliases(data): - print data, type(data) - sys.stdout.flush() - if data in [None, ()]: - return True - if isinstance(data, (str, unicode, bool, int, float)): - return True - yaml.representer.SafeRepresenter.ignore_aliases = staticmethod( - ignore_aliases) - import yaml from yaml.representer import RepresenterError diff --git a/hooke/util/yaml.py b/hooke/util/yaml.py new file mode 100644 index 0000000..22eeb14 --- /dev/null +++ b/hooke/util/yaml.py @@ -0,0 +1,60 @@ +# Copyright + +"""Add representers to YAML to support Hooke. + +Without introspection, YAML cannot decide how to save some +objects. By refusing to save these objects, we obviously loose +that information, so make sure the things you drop are either +stored somewhere else or not important. + +>>> import yaml +>>> a = numpy.array([1,2,3]) +>>> print yaml.dump(a) +null +... + + +The default behavior is to crash. + +>>> yaml.Dumper.yaml_representers.pop(numpy.ndarray) # doctest: +ELLIPSIS + +>>> print yaml.dump(a) +Traceback (most recent call last): + ... + if data in [None, ()]: +TypeError: data type not understood + +Restore the representer for future tests. + +>>> yaml.add_representer(numpy.ndarray, ndarray_representer) +""" + +from __future__ import absolute_import +import sys + +import numpy +import yaml #from yaml.representer import Representer + +from ..curve import Data + + +if False: # YAML dump debugging code + """To help isolate data types etc. that give YAML problems. + + This is usually caused by external C modules (e.g. numpy) that + define new types (e.g. numpy.dtype) which YAML cannot inspect. + """ + def ignore_aliases(data): + print data, type(data) + sys.stdout.flush() + if data in [None, ()]: + return True + if isinstance(data, (str, unicode, bool, int, float)): + return True + yaml.representer.SafeRepresenter.ignore_aliases = staticmethod( + ignore_aliases) + +def ndarray_representer(dumper, data): + return dumper.represent_none(None) +yaml.add_representer(numpy.ndarray, ndarray_representer) +yaml.add_representer(Data, ndarray_representer) -- 2.26.2