summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2013-01-29 18:03:22 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2013-01-29 18:04:18 +0000
commitee01dea68ecd0822785ef574f7c2ddcb44d0cafa (patch)
tree49f08d357cc8ad068b36c1c9df7ead9d1b72d077
parenta50a5411db21f4cde449d1bb26f85b8bbee275ac (diff)
parente06eafcbf0784271f51c0936852d1e97c0ccce8b (diff)
downloadmorph-ee01dea68ecd0822785ef574f7c2ddcb44d0cafa.tar.gz
Merge branch 'liw/soft-pyyaml-dep'
Merge commit fixes up a copyright year and removes EOL whitespace
-rwxr-xr-xcheck11
-rw-r--r--morphlib/__init__.py14
-rw-r--r--morphlib/morph2.py2
-rw-r--r--morphlib/morph2_tests.py34
-rw-r--r--morphlib/morphologyfactory.py3
-rw-r--r--morphlib/yamlparse.py184
-rw-r--r--morphlib/yamlparse_tests.py15
7 files changed, 151 insertions, 112 deletions
diff --git a/check b/check
index 7288e55f..22db382b 100755
--- a/check
+++ b/check
@@ -2,7 +2,7 @@
#
# Run test suite for morph.
#
-# Copyright (C) 2011, 2012 Codethink Limited
+# Copyright (C) 2011-2013 Codethink Limited
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -23,9 +23,16 @@ python setup.py clean check
cmdtest tests
cmdtest tests.branching
cmdtest tests.merging
-if [ $(whoami) = root ] && command -v mkfs.btrfs > /dev/null
+if [ $(whoami) = root ] && command -v mkfs.btrfs > /dev/null &&
+ python -c "
+import morphlib, sys
+if not morphlib.got_yaml:
+ sys.exit(1)
+" > /dev/null 2>&1
then
cmdtest tests.as-root
+else
+ echo "NOT RUNNING tests.as-root"
fi
if [ -d .git ];
diff --git a/morphlib/__init__.py b/morphlib/__init__.py
index aba7a4d6..0f60642c 100644
--- a/morphlib/__init__.py
+++ b/morphlib/__init__.py
@@ -17,6 +17,19 @@
'''Baserock library.'''
+# Import yaml if available. This can go away once Baserock has made a
+# release that includes yaml (also in its staging filler).
+try:
+ import yaml
+except ImportError:
+ got_yaml = False
+ class YAMLError(Exception):
+ pass
+else:
+ got_yaml = True
+ YAMLError = yaml.YAMLError
+
+
import cliapp
import gitversion
@@ -57,6 +70,7 @@ import stagingarea
import stopwatch
import tempdir
import util
+
import yamlparse
import app # this needs to be last
diff --git a/morphlib/morph2.py b/morphlib/morph2.py
index edf7bb31..3a3ad679 100644
--- a/morphlib/morph2.py
+++ b/morphlib/morph2.py
@@ -70,7 +70,7 @@ class Morphology(object):
try:
self._dict = self._load_json(text)
self._dumper = self._dump_json
- except Exception, e:
+ except Exception, e: # pragma: no cover
self._dict = morphlib.yamlparse.load(text)
self._dumper = morphlib.yamlparse.dump
self._set_defaults()
diff --git a/morphlib/morph2_tests.py b/morphlib/morph2_tests.py
index 34df4657..7a819556 100644
--- a/morphlib/morph2_tests.py
+++ b/morphlib/morph2_tests.py
@@ -17,6 +17,7 @@
import StringIO
import unittest
+import morphlib
from morphlib.morph2 import Morphology
@@ -41,22 +42,23 @@ class MorphologyTests(unittest.TestCase):
self.assertEqual(m['max-jobs'], None)
self.assertEqual(m['chunks'], [])
- def test_parses_simple_yaml_chunk(self):
- m = Morphology('''
- name: foo
- kind: chunk
- build-system: manual
- ''')
-
- self.assertEqual(m['name'], 'foo')
- self.assertEqual(m['kind'], 'chunk')
- self.assertEqual(m['build-system'], 'manual')
- self.assertEqual(m['configure-commands'], None)
- self.assertEqual(m['build-commands'], None)
- self.assertEqual(m['test-commands'], None)
- self.assertEqual(m['install-commands'], None)
- self.assertEqual(m['max-jobs'], None)
- self.assertEqual(m['chunks'], [])
+ if morphlib.got_yaml:
+ def test_parses_simple_yaml_chunk(self):
+ m = Morphology('''
+ name: foo
+ kind: chunk
+ build-system: manual
+ ''')
+
+ self.assertEqual(m['name'], 'foo')
+ self.assertEqual(m['kind'], 'chunk')
+ self.assertEqual(m['build-system'], 'manual')
+ self.assertEqual(m['configure-commands'], None)
+ self.assertEqual(m['build-commands'], None)
+ self.assertEqual(m['test-commands'], None)
+ self.assertEqual(m['install-commands'], None)
+ self.assertEqual(m['max-jobs'], None)
+ self.assertEqual(m['chunks'], [])
def test_sets_stratum_chunks_repo_and_morph_from_name(self):
m = Morphology('''
diff --git a/morphlib/morphologyfactory.py b/morphlib/morphologyfactory.py
index 261dc908..6625d375 100644
--- a/morphlib/morphologyfactory.py
+++ b/morphlib/morphologyfactory.py
@@ -13,7 +13,6 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-import yaml
import morphlib
import cliapp
@@ -83,7 +82,7 @@ class MorphologyFactory(object):
try:
morphology = morphlib.morph2.Morphology(text)
- except yaml.YAMLError as e:
+ except morphlib.YAMLError as e: # pragma: no cover
raise morphlib.Error("Error parsing %s: %s" %
(filename, str(e)))
diff --git a/morphlib/yamlparse.py b/morphlib/yamlparse.py
index 7f8b00e5..7e591b08 100644
--- a/morphlib/yamlparse.py
+++ b/morphlib/yamlparse.py
@@ -13,13 +13,18 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-import yaml
-import yaml.constructor
+import morphlib
from morphlib.util import OrderedDict
-class OrderedDictYAMLLoader(yaml.Loader):
- """A YAML loader that loads mappings into ordered dictionaries.
+if morphlib.got_yaml: # pragma: no cover
+ yaml = morphlib.yaml
+
+
+if morphlib.got_yaml: # pragma: no cover
+
+ class OrderedDictYAMLLoader(yaml.Loader):
+ """A YAML loader that loads mappings into ordered dictionaries.
When YAML is loaded with this Loader, it loads mappings as ordered
dictionaries, so the order the keys were written in is maintained.
@@ -27,47 +32,48 @@ class OrderedDictYAMLLoader(yaml.Loader):
When combined with the OrderedDictYAMLDumper, this allows yaml documents
to be written out in a similar format to they were read.
- """
-
- def __init__(self, *args, **kwargs):
- yaml.Loader.__init__(self, *args, **kwargs)
-
- # When YAML encounters a mapping (which YAML identifies with
- # the given tag), it will use construct_yaml_map to read it as
- # an OrderedDict.
- self.add_constructor(u'tag:yaml.org,2002:map',
- type(self).construct_yaml_map)
-
- def construct_yaml_map(self, node):
- data = OrderedDict()
- yield data
- value = self.construct_mapping(node)
- data.update(value)
-
- def construct_mapping(self, node, deep=False):
- if isinstance(node, yaml.MappingNode):
- self.flatten_mapping(node)
- else:
- raise yaml.constructor.ConstructorError(
- None, None,
- 'expected a mapping node, but found %s' % node.id,
- node.start_mark)
-
- mapping = OrderedDict()
- for key_node, value_node in node.value:
- key = self.construct_object(key_node, deep=deep)
- try:
- hash(key)
- except TypeError, exc:
- raise yaml.constructor.ConstructorError(
- 'while constructing a mapping', node.start_mark,
- 'found unacceptable key (%s)' % exc, key_node.start_mark)
- value = self.construct_object(value_node, deep=deep)
- mapping[key] = value
- return mapping
+ """
-class OrderedDictYAMLDumper(yaml.Dumper):
- """A YAML dumper that will dump OrderedDicts as mappings.
+ def __init__(self, *args, **kwargs):
+ yaml.Loader.__init__(self, *args, **kwargs)
+
+ # When YAML encounters a mapping (which YAML identifies with
+ # the given tag), it will use construct_yaml_map to read it as
+ # an OrderedDict.
+ self.add_constructor(u'tag:yaml.org,2002:map',
+ type(self).construct_yaml_map)
+
+ def construct_yaml_map(self, node):
+ data = OrderedDict()
+ yield data
+ value = self.construct_mapping(node)
+ data.update(value)
+
+ def construct_mapping(self, node, deep=False):
+ if isinstance(node, yaml.MappingNode):
+ self.flatten_mapping(node)
+ else:
+ raise yaml.constructor.ConstructorError(
+ None, None,
+ 'expected a mapping node, but found %s' % node.id,
+ node.start_mark)
+
+ mapping = OrderedDict()
+ for key_node, value_node in node.value:
+ key = self.construct_object(key_node, deep=deep)
+ try:
+ hash(key)
+ except TypeError, exc:
+ raise yaml.constructor.ConstructorError(
+ 'while constructing a mapping', node.start_mark,
+ 'found unacceptable key (%s)' % exc,
+ key_node.start_mark)
+ value = self.construct_object(value_node, deep=deep)
+ mapping[key] = value
+ return mapping
+
+ class OrderedDictYAMLDumper(yaml.Dumper):
+ """A YAML dumper that will dump OrderedDicts as mappings.
When YAML is dumped with this Dumper, it dumps OrderedDicts as
mappings, preserving the key order, so the order the keys were
@@ -76,44 +82,52 @@ class OrderedDictYAMLDumper(yaml.Dumper):
When combined with the OrderedDictYAMLDumper, this allows yaml documents
to be written out in a similar format to they were read.
- """
-
- def __init__(self, *args, **kwargs):
- yaml.Dumper.__init__(self, *args, **kwargs)
-
- # When YAML sees an OrderedDict, use represent_ordered_dict to dump it
- self.add_representer(OrderedDict,
- type(self).represent_ordered_dict)
-
- def represent_ordered_dict(self, odict):
- return self.represent_ordered_mapping(u'tag:yaml.org,2002:map', odict)
-
- def represent_ordered_mapping(self, tag, omap):
- value = []
- node = yaml.MappingNode(tag, value)
- if self.alias_key is not None:
- self.represented_objects[self.alias_key] = node
- best_style = True
- for item_key, item_value in omap.iteritems():
- node_key = self.represent_data(item_key)
- node_value = self.represent_data(item_value)
- if not (isinstance(node_key, yaml.ScalarNode) and
- not node_key.style):
- best_style = False # pragma: no cover
- if not (isinstance(node_value, yaml.ScalarNode) and
- not node_value.style):
- best_style = False # pragma: no cover
- value.append((node_key, node_value))
- if self.default_flow_style is not None:
- node.flow_style = self.default_flow_style
- else:
- node.flow_style = best_style # pragma: no cover
- return node
-
-def load(*args, **kwargs):
- return yaml.load(Loader=OrderedDictYAMLLoader, *args, **kwargs)
-
-def dump(*args, **kwargs):
- if 'default_flow_style' not in kwargs:
- kwargs['default_flow_style'] = False
- return yaml.dump(Dumper=OrderedDictYAMLDumper, *args, **kwargs)
+ """
+
+ def __init__(self, *args, **kwargs):
+ yaml.Dumper.__init__(self, *args, **kwargs)
+
+ # When YAML sees an OrderedDict, use represent_ordered_dict to
+ # dump it
+ self.add_representer(OrderedDict,
+ type(self).represent_ordered_dict)
+
+ def represent_ordered_dict(self, odict):
+ return self.represent_ordered_mapping(
+ u'tag:yaml.org,2002:map', odict)
+
+ def represent_ordered_mapping(self, tag, omap):
+ value = []
+ node = yaml.MappingNode(tag, value)
+ if self.alias_key is not None:
+ self.represented_objects[self.alias_key] = node
+ best_style = True
+ for item_key, item_value in omap.iteritems():
+ node_key = self.represent_data(item_key)
+ node_value = self.represent_data(item_value)
+ if not (isinstance(node_key, yaml.ScalarNode) and
+ not node_key.style):
+ best_style = False # pragma: no cover
+ if not (isinstance(node_value, yaml.ScalarNode) and
+ not node_value.style):
+ best_style = False # pragma: no cover
+ value.append((node_key, node_value))
+ if self.default_flow_style is not None:
+ node.flow_style = self.default_flow_style
+ else:
+ node.flow_style = best_style # pragma: no cover
+ return node
+
+ def load(*args, **kwargs):
+ return yaml.load(Loader=OrderedDictYAMLLoader, *args, **kwargs)
+
+ def dump(*args, **kwargs):
+ if 'default_flow_style' not in kwargs:
+ kwargs['default_flow_style'] = False
+ return yaml.dump(Dumper=OrderedDictYAMLDumper, *args, **kwargs)
+
+else: # pragma: no cover
+ def load(*args, **kwargs):
+ raise morphlib.Error('YAML not available')
+ def dump(*args, **kwargs):
+ raise morphlib.Error('YAML not available')
diff --git a/morphlib/yamlparse_tests.py b/morphlib/yamlparse_tests.py
index cb658e15..f5c2569b 100644
--- a/morphlib/yamlparse_tests.py
+++ b/morphlib/yamlparse_tests.py
@@ -15,17 +15,20 @@
import unittest
-try:
- from collections import OrderedDict
-except ImportError:
- from ordereddict import OrderedDict
-import yaml
-
+import morphlib
import morphlib.yamlparse as yamlparse
+from morphlib.util import OrderedDict
+
+if morphlib.got_yaml:
+ yaml = morphlib.yaml
class YAMLParseTests(unittest.TestCase):
+ def run(self, *args, **kwargs):
+ if morphlib.got_yaml:
+ return unittest.TestCase.run(self, *args, **kwargs)
+
example_text = '''\
name: foo
kind: chunk