Mercurial > piecrust2
diff piecrust/configuration.py @ 67:563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 29 Aug 2014 16:42:15 -0700 |
parents | 474c9882decf |
children | d9e494df2a99 |
line wrap: on
line diff
--- a/piecrust/configuration.py Fri Aug 29 16:41:16 2014 -0700 +++ b/piecrust/configuration.py Fri Aug 29 16:42:15 2014 -0700 @@ -1,6 +1,8 @@ import re import logging +import collections import yaml +from yaml.constructor import ConstructorError logger = logging.getLogger(__name__) @@ -114,10 +116,29 @@ m = header_regex.match(text) if m is not None: header = str(m.group('header')) - config = yaml.load(header, Loader=yaml.BaseLoader) + config = yaml.load(header, Loader=OrderedDictYAMLLoader) offset = m.end() else: config = {} offset = 0 return config, offset + +class OrderedDictYAMLLoader(yaml.BaseLoader): + """ A YAML loader that loads mappings into ordered dictionaries. + """ + def construct_mapping(self, node, deep=False): + if not isinstance(node, yaml.MappingNode): + raise ConstructorError(None, None, + "expected a mapping node, but found %s" % node.id, + node.start_mark) + mapping = collections.OrderedDict() + for key_node, value_node in node.value: + key = self.construct_object(key_node, deep=deep) + if not isinstance(key, collections.Hashable): + raise ConstructorError("while constructing a mapping", node.start_mark, + "found unhashable key", key_node.start_mark) + value = self.construct_object(value_node, deep=deep) + mapping[key] = value + return mapping +