comparison configmix/yaml.py @ 5:dc058099a4cb

Renamed the project from "MixConfig" to "ConfigMix"
author Franz Glasner <hg@dom66.de>
date Tue, 08 Mar 2016 20:11:17 +0100
parents mixconfig/yaml.py@bedc4f95b9e9
children ce290b10dac5
comparison
equal deleted inserted replaced
4:f76d85ccc5b9 5:dc058099a4cb
1 # -*- coding: utf-8 -*-
2 r"""Simple wrapper for yaml to support all-unicode strings when loading
3 configuration files.
4
5 """
6
7 from __future__ import division, print_function, absolute_import
8
9 try:
10 from collections import OrderedDict
11 except ImportError:
12 try:
13 from ordereddict import OrderedDict
14 except ImportError:
15 OrderedDict = None
16 import yaml
17 import yaml.constructor
18
19
20 __all__ = ["safe_load", "safe_load_all", "load", "load_all"]
21
22
23 class ConfigLoader(yaml.Loader):
24
25 """A YAML loader, which makes all !!str strings to Unicode. Standard
26 PyYAML does this only in the non-ASCII case.
27
28 If an `OrderedDict` implementation is available then all "map" and
29 "omap" nodes are constructed as `OrderedDict`.
30 This is against YAML specs but within configuration files it seems
31 more natural.
32
33 """
34
35 def construct_yaml_str(self, node):
36 return self.construct_scalar(node)
37
38 if OrderedDict:
39
40 #
41 # From https://pypi.python.org/pypi/yamlordereddictloader/0.1.1
42 # (MIT License)
43 #
44
45 def construct_yaml_map(self, node):
46 data = OrderedDict()
47 yield data
48 value = self.construct_mapping(node)
49 data.update(value)
50
51 def construct_mapping(self, node, deep=False):
52 if isinstance(node, yaml.MappingNode):
53 self.flatten_mapping(node)
54 else:
55 raise yaml.constructor.ConstructorError(None, None,
56 'expected a mapping node, but found %s' % node.id,
57 node.start_mark)
58
59 mapping = OrderedDict()
60 for key_node, value_node in node.value:
61 key = self.construct_object(key_node, deep=deep)
62 try:
63 hash(key)
64 except TypeError as err:
65 raise yaml.constructor.ConstructorError(
66 'while constructing a mapping', node.start_mark,
67 'found unacceptable key (%s)' % err, key_node.start_mark)
68 value = self.construct_object(value_node, deep=deep)
69 mapping[key] = value
70 return mapping
71
72
73 ConfigLoader.add_constructor(
74 "tag:yaml.org,2002:str",
75 ConfigLoader.construct_yaml_str)
76 if OrderedDict:
77 ConfigLoader.add_constructor(
78 "tag:yaml.org,2002:map",
79 ConfigLoader.construct_yaml_map)
80 ConfigLoader.add_constructor(
81 "tag:yaml.org,2002:omap",
82 ConfigLoader.construct_yaml_map)
83
84
85 class ConfigSafeLoader(yaml.SafeLoader):
86
87 """A safe YAML loader, which makes all !!str strings to Unicode.
88 Standard PyYAML does this only in the non-ASCII case.
89
90 If an `OrderedDict` implementation is available then all "map" and
91 "omap" nodes are constructed as `OrderedDict`.
92 This is against YAML specs but within configuration files it seems
93 more natural.
94
95 """
96
97 def construct_yaml_str(self, node):
98 return self.construct_scalar(node)
99
100 if OrderedDict:
101
102 #
103 # From https://pypi.python.org/pypi/yamlordereddictloader/0.1.1
104 # (MIT License)
105 #
106
107 def construct_yaml_map(self, node):
108 data = OrderedDict()
109 yield data
110 value = self.construct_mapping(node)
111 data.update(value)
112
113 def construct_mapping(self, node, deep=False):
114 if isinstance(node, yaml.MappingNode):
115 self.flatten_mapping(node)
116 else:
117 raise yaml.constructor.ConstructorError(None, None,
118 'expected a mapping node, but found %s' % node.id,
119 node.start_mark)
120
121 mapping = OrderedDict()
122 for key_node, value_node in node.value:
123 key = self.construct_object(key_node, deep=deep)
124 try:
125 hash(key)
126 except TypeError as err:
127 raise yaml.constructor.ConstructorError(
128 'while constructing a mapping', node.start_mark,
129 'found unacceptable key (%s)' % err, key_node.start_mark)
130 value = self.construct_object(value_node, deep=deep)
131 mapping[key] = value
132 return mapping
133
134
135 ConfigSafeLoader.add_constructor(
136 "tag:yaml.org,2002:str",
137 ConfigSafeLoader.construct_yaml_str)
138 if OrderedDict:
139 ConfigSafeLoader.add_constructor(
140 "tag:yaml.org,2002:map",
141 ConfigSafeLoader.construct_yaml_map)
142 ConfigSafeLoader.add_constructor(
143 "tag:yaml.org,2002:omap",
144 ConfigSafeLoader.construct_yaml_map)
145
146
147 def load(stream, Loader=ConfigLoader):
148 return yaml.load(stream, Loader)
149
150
151 def load_all(stream, Loader=ConfigLoader):
152 return yaml.load_all(stream, Loader)
153
154
155 def safe_load(stream):
156 return yaml.load(stream, Loader=ConfigSafeLoader)
157
158
159 def safe_load_all(stream):
160 return yaml.load_all(stream, Loader=ConfigSafeLoader)