-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample_dumper.py
More file actions
156 lines (142 loc) · 5.37 KB
/
Copy pathexample_dumper.py
File metadata and controls
156 lines (142 loc) · 5.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import yaml
import sys
loader_set = False
x = 1
print repr(sys.argv)
while x < len(sys.argv):
if sys.argv[x].startswith('-'):
arg = sys.argv[x]
if arg == '-l':
from yaml import Loader as Loader
elif arg == '-c':
from yaml import CLoader as Loader
elif arg == '-L':
from yaml import SafeLoader as Loader
elif arg == '-C':
from yaml import CSafeLoader as Loader
else:
raise RuntimeError("Didn't recognize %r" % (arg,))
loader_set = True
else:
break
x += 1
if not loader_set:
from yaml import Loader as Loader
files = sys.argv[x:]
if not files:
files = ['yaml_examples.yml']
# If you *don't* specify your loader in some places, you'll
# break. Always pass the Loader=Loader parameter, and set the
# yaml_loader=Loader class variable.
class GenericScalar(yaml.YAMLObject):
yaml_loader=Loader
def __init__(self, value):
self.value = value
def __repr__(self):
return "%s(%r)" % (type(self).__name__, self.value,)
@classmethod
def from_yaml(cls, loader, node):
return cls(loader.construct_scalar(node))
# A bunch of scalar based classes to get the examples in the spec loading correctly.
class Something(GenericScalar):
yaml_tag = u'!something'
class Local(GenericScalar):
yaml_tag = u'!local'
class Bar(GenericScalar):
yaml_tag = u'!bar'
class Huh(GenericScalar):
yaml_tag = u'tag:ben-kiki.org,2000:type'
class Stringy(GenericScalar):
yaml_tag = u'!str'
# Not sure the parser is getting this right. Should !!str, really pick up this tag?
yaml.add_constructor(u'tag:yaml.org,2002:str,', lambda l, n: "")
def construct_mapping_kludge(loader, node):
""" This constructor painfully steps through the node and checks
that each key is hashable. Actually, what it does is checks
whether it knows how to *make* it hashable, and if so, does that.
If not it just lets it through and hopes for the best. But the
common problem cases are handled here. If you're constructing
objects directly from YAML, just make them immutable and hashable! """
def anything(node):
if isinstance(node, yaml.ScalarNode):
return loader.construct_scalar(node)
elif isinstance(node, yaml.SequenceNode):
return loader.construct_sequence(node)
elif isinstance(node, yaml.MappingNode):
return construct_mapping_kludge(loader, node)
def make_hashable(value):
""" Reconstructs a non-hashable value. """
if isinstance(value, list):
return tuple(map(make_hashable, value))
elif isinstance(value, set):
return frozenset(value)
elif isinstance(value, dict):
return frozenset((make_hashable(key), make_hashable(val))
for key, val in value.items())
else:
return value
def new_items():
for k, v in node.value:
yield (make_hashable(anything(k)), anything(v))
return dict(new_items())
yaml.add_constructor(u'tag:yaml.org,2002:map', construct_mapping_kludge, Loader=Loader)
class BunchOShapes(yaml.YAMLObject):
""" You can figure out the tag from the error message:
yaml.constructor.ConstructorError: could not determine a
constructor for the tag 'tag:clarkevans.com,2002:shape'"""
yaml_tag = u'tag:clarkevans.com,2002:shape'
yaml_loader=Loader
def __init__(self, *shapes):
self.shapes = shapes
def __repr__(self):
return "BunchOShapes(%r)" % (self.shapes,)
@classmethod
def from_yaml(cls, loader, node):
return cls(*loader.construct_sequence(node))
class Circle(yaml.YAMLObject):
yaml_tag=u'tag:clarkevans.com,2002:circle'
yaml_loader=Loader
def __init__(self, center, radius):
self.center = center
self.radius = radius
def __repr__(self):
return "Circle(%r, %r)" % (self.center, self.radius)
class Line(yaml.YAMLObject):
yaml_tag=u'tag:clarkevans.com,2002:line'
yaml_loader=Loader
def __init__(self, start, finish):
self.start = start
self.finish = finish
def __repr__(self):
return "Line(%r, %r)" % (self.start, self.finish)
class Label(yaml.YAMLObject):
yaml_tag=u'tag:clarkevans.com,2002:label'
yaml_loader=Loader
def __init__(self, start, color, text):
self.start = start
self.color = color
self.text = text
def __repr__(self):
return "Label(%r, %r, %r)" % (self.start, self.color, self.text)
class Invoice(yaml.YAMLObject):
yaml_tag=u'tag:clarkevans.com,2002:invoice'
yaml_loader=Loader
def __init__(self, **args):
self.data = args
print repr(args)
def __repr__(self):
data = getattr(self, 'data', {})
return "Invoice(%s)" % (', '.join("%s=%r" % (k, v) for k, v in data.items()),)
@classmethod
def from_yaml(cls, loader, node):
""" I suspect the default won't work with invoices (it doesn't
call the __init__ method) because there are -'s in some of the
keys. """
value = loader.construct_mapping(node)
args = dict((k.replace('-', '_'), v) for k, v in value.items())
return cls(**args)
for name in files:
with open(name, "r") as yaml_fh:
print("=============== %s ================" % (name,))
for doc in yaml.load_all(yaml_fh, Loader=Loader):
print(repr(doc))