Changeset 129
- Timestamp:
- 04/01/06 16:28:20 (7 years ago)
- Location:
- pyyaml/branches/working-on-emitter
- Files:
-
- 5 added
- 2 edited
-
lib/yaml/emitter.py (modified) (6 diffs)
-
tests/data/aliases.events (added)
-
tests/data/documents.events (added)
-
tests/data/mappings.events (added)
-
tests/data/scalars.events (added)
-
tests/data/sequences.events (added)
-
tests/test_emitter.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
pyyaml/branches/working-on-emitter/lib/yaml/emitter.py
r127 r129 21 21 self.states = [] 22 22 self.state = self.expect_stream_start 23 self.levels = [] 24 self.level = 0 25 self.soft_space = False 23 self.indents = [] 24 self.indent = None 25 self.flow_level = 0 26 self.key_context = False 27 self.space = True 28 self.line = True 29 self.allow_inline_collection = False 30 self.allow_indentless_sequence = False 31 self.simple_key = False 32 self.event_queue = [] 26 33 27 34 def emit(self, event): 35 if self.event_queue: 36 self.event_queue.append(event) 37 event = self.event_queue.pop(0) 28 38 self.state(event) 39 40 def push_back(self, event): 41 self.event_queue.insert(0, event) 29 42 30 43 def expect_stream_start(self, event): … … 39 52 self.states.append(self.expect_document_end) 40 53 self.state = self.expect_root_node 54 self.allow_inline_collection = False 55 self.allow_indentless_sequence = False 41 56 elif isinstance(event, StreamEndEvent): 42 57 self.writer.flush() … … 49 64 self.write_document_end() 50 65 self.state = self.expect_document_start 66 self.allow_inline_collection = False 67 self.allow_indentless_sequence = False 51 68 else: 52 69 raiseEmitterError("expected DocumentEndEvent, but got %s" % event.__class__.__name__) … … 56 73 57 74 def expect_node(self, event): 75 empty = None 76 if isinstance(event, (SequenceEvent, MappingEvent)): 77 if not self.event_queue: 78 return self.push_back(event) 79 empty = isinstance(self.event_queue[0], CollectionEndEvent) 58 80 if isinstance(event, AliasEvent): 59 self.write_anchor("*", event.anchor) 60 self.state = self.states.pop() 61 elif isinstance(event, NodeEvent): 81 self.expect_alias(event) 82 elif isinstance(event, (ScalarEvent, SequenceEvent, MappingEvent)): 62 83 if event.anchor: 63 84 self.write_anchor("&", event.anchor) 64 if event.tag: 85 self.allow_inline_collection = False 86 if event.tag not in [None, u'!']: 65 87 self.write_tag(event.tag) 88 self.allow_inline_collection = False 66 89 if isinstance(event, ScalarEvent): 67 self.write_scalar(event.value) 68 self.state = self.states.pop() 90 self.expect_scalar(event) 69 91 elif isinstance(event, SequenceEvent): 70 self.write_collection_start("[") 71 self.level += 1 72 self.state = self.expect_first_sequence_item 92 self.expect_sequence(event, empty) 73 93 elif isinstance(event, MappingEvent): 74 self.write_collection_start("{") 75 self.level += 1 76 self.state = self.expect_first_mapping_key 94 self.expect_mapping(event, empty) 77 95 else: 78 96 raise EmitterError("Expected NodeEvent, but got %s" % event.__class__.__name__) 79 97 80 def expect_first_sequence_item(self, event): 81 if isinstance(event, CollectionEndEvent): 82 self.write_collection_end("]") 83 self.state = self.states.pop() 84 else: 85 self.write_indent() 86 self.states.append(self.expect_sequence_item) 87 self.expect_node(event) 88 89 def expect_sequence_item(self, event): 90 if isinstance(event, CollectionEndEvent): 91 self.level -= 1 92 self.write_indent() 93 self.write_collection_end("]") 94 self.state = self.states.pop() 95 else: 98 def expect_alias(self, event): 99 self.write_anchor("*", event.anchor) 100 self.state = self.states.pop() 101 102 def expect_scalar(self, event): 103 self.indents.append(self.indent) 104 if self.indent is None: 105 self.indent = 2 106 else: 107 self.indent += 2 108 self.write_scalar(event.value, event.implicit, event.style) 109 self.indent = self.indents.pop() 110 self.state = self.states.pop() 111 self.allow_inline_collection = False 112 self.allow_indentless_sequence = False 113 114 def expect_sequence(self, event, empty): 115 if self.flow_level or event.flow or empty: 116 self.write_indicator("[", need_space=True, provide_space=True) 117 self.flow_level += 1 118 self.indents.append(self.indent) 119 if self.indent is None: 120 self.indent = 2 121 else: 122 self.indent += 2 123 self.state = self.expect_first_flow_sequence_item 124 else: 125 self.indents.append(self.indent) 126 if self.indent is None: 127 self.indent = 0 128 else: 129 self.indent += 2 130 self.state = self.expect_first_block_sequence_item 131 132 def expect_mapping(self, event, empty): 133 if self.flow_level or event.flow or empty: 134 self.write_indicator("{", need_space=True, provide_space=True) 135 self.flow_level += 1 136 self.indents.append(self.indent) 137 if self.indent is None: 138 self.indent = 2 139 else: 140 self.indent += 2 141 self.state = self.expect_first_flow_mapping_key 142 else: 143 self.indents.append(self.indent) 144 if self.indent is None: 145 self.indent = 0 146 else: 147 self.indent += 2 148 self.state = self.expect_first_block_mapping_key 149 150 def expect_first_flow_sequence_item(self, event): 151 if isinstance(event, CollectionEndEvent): 152 self.indent = self.indents.pop() 153 self.write_indicator("]", provide_space=True) 154 self.flow_level -= 1 155 self.state = self.states.pop() 156 else: 157 self.write_indent() 158 self.states.append(self.expect_flow_sequence_item) 159 self.state = self.expect_node 160 self.expect_node(event) 161 162 def expect_flow_sequence_item(self, event): 163 if isinstance(event, CollectionEndEvent): 96 164 self.write_indicator(",") 97 self.write_indent() 98 self.states.append(self.expect_sequence_item) 99 self.expect_node(event) 100 101 def expect_first_mapping_key(self, event): 102 if isinstance(event, CollectionEndEvent): 103 self.write_collection_end("}") 104 self.state = self.states.pop() 105 else: 106 self.write_indent() 107 self.write_indicator("?") 108 self.states.append(self.expect_mapping_value) 109 self.expect_node(event) 110 111 def expect_mapping_key(self, event): 112 if isinstance(event, CollectionEndEvent): 113 self.level -= 1 114 self.write_indent() 115 self.write_collection_end("}") 165 self.indent = self.indents.pop() 166 self.write_indent() 167 self.write_indicator("]") 168 self.flow_level -= 1 116 169 self.state = self.states.pop() 117 170 else: 118 171 self.write_indicator(",") 119 172 self.write_indent() 120 self.write_indicator("?") 121 self.states.append(self.expect_mapping_value) 122 self.expect_node(event) 123 124 def expect_mapping_value(self, event): 125 self.write_indent() 126 self.write_indicator(":") 127 self.states.append(self.expect_mapping_key) 173 self.states.append(self.expect_flow_sequence_item) 174 self.state = self.expect_node 175 self.expect_node(event) 176 177 def expect_first_block_sequence_item(self, event): 178 assert not isinstance(event, CollectionEndEvent) 179 if not self.allow_inline_collection: 180 if self.allow_indentless_sequence: 181 self.indent = self.indents.pop() 182 self.indents.append(self.indent) 183 self.write_indent() 184 self.write_indicator("-", need_space=True) 185 self.allow_indentless_sequence = False 186 self.allow_inline_collection = True 187 self.states.append(self.expect_block_sequence_item) 188 self.state = self.expect_node 189 self.expect_node(event) 190 191 def expect_block_sequence_item(self, event): 192 if isinstance(event, CollectionEndEvent): 193 self.indent = self.indents.pop() 194 self.state = self.states.pop() 195 else: 196 self.write_indent() 197 self.write_indicator("-", need_space=True) 198 self.allow_indentless_sequence = False 199 self.allow_inline_collection = True 200 self.states.append(self.expect_block_sequence_item) 201 self.state = self.expect_node 202 self.expect_node(event) 203 204 def expect_first_flow_mapping_key(self, event): 205 if isinstance(event, CollectionEndEvent): 206 self.indent = self.indents.pop() 207 self.write_indicator("}") 208 self.flow_level -= 1 209 self.state = self.states.pop() 210 else: 211 self.write_indent() 212 if self.is_simple(event): 213 self.simple_key = True 214 else: 215 self.write_indicator("?", need_space=True) 216 self.states.append(self.expect_flow_mapping_value) 217 self.state = self.expect_node 218 self.expect_node(event) 219 220 def expect_flow_mapping_key(self, event): 221 if isinstance(event, CollectionEndEvent): 222 self.indent = self.indents.pop() 223 self.write_indent() 224 self.write_indicator("}") 225 self.flow_level -= 1 226 self.state = self.states.pop() 227 else: 228 self.write_indicator(",") 229 self.write_indent() 230 if self.is_simple(event): 231 self.simple_key = True 232 else: 233 self.write_indicator("?", need_space=True) 234 self.states.append(self.expect_flow_mapping_value) 235 self.state = self.expect_node 236 self.expect_node(event) 237 238 def expect_flow_mapping_value(self, event): 239 if self.simple_key: 240 self.write_indicator(":", need_space=False) 241 self.simple_key = False 242 else: 243 self.write_indent() 244 self.write_indicator(":", need_space=True) 245 self.states.append(self.expect_flow_mapping_key) 246 self.state = self.expect_node 247 self.expect_node(event) 248 249 def expect_first_block_mapping_key(self, event): 250 assert not isinstance(event, CollectionEndEvent) 251 simple = self.is_simple(event) 252 if simple is None: 253 return self.push_back(event) 254 if not self.allow_inline_collection: 255 self.write_indent() 256 if self.is_simple(event): 257 self.allow_indentless_sequence = True 258 self.allow_inline_collection = False 259 self.simple_key = True 260 else: 261 self.write_indicator("?", need_space=True) 262 self.allow_indentless_sequence = True 263 self.allow_inline_collection = True 264 self.states.append(self.expect_block_mapping_value) 265 self.state = self.expect_node 266 self.expect_node(event) 267 268 def expect_block_mapping_key(self, event): 269 if isinstance(event, CollectionEndEvent): 270 self.indent = self.indents.pop() 271 self.state = self.states.pop() 272 else: 273 self.write_indent() 274 if self.is_simple(event): 275 self.allow_indentless_sequence = True 276 self.allow_inline_collection = False 277 self.simple_key = True 278 else: 279 self.write_indicator("?", need_space=True) 280 self.allow_indentless_sequence = True 281 self.allow_inline_collection = True 282 self.states.append(self.expect_block_mapping_value) 283 self.state = self.expect_node 284 self.expect_node(event) 285 286 def expect_block_mapping_value(self, event): 287 if self.simple_key: 288 self.write_indicator(":", need_space=False) 289 self.allow_indentless_sequence = True 290 self.allow_inline_collection = False 291 self.simple_key = False 292 else: 293 self.write_indent() 294 self.write_indicator(":", need_space=True) 295 self.allow_indentless_sequence = True 296 self.allow_inline_collection = True 297 self.states.append(self.expect_block_mapping_key) 298 self.state = self.expect_node 128 299 self.expect_node(event) 129 300 … … 132 303 133 304 def write_document_start(self): 134 self.writer.write("%YAML 1.1\n") 305 self.writer.write("%YAML 1.1") 306 self.write_line_break() 135 307 self.writer.write("---") 136 self.soft_space = True 308 self.space = False 309 self.line = False 137 310 138 311 def write_document_end(self): 139 self.writer.write("\n...\n") 140 self.soft_space = False 141 142 def write_collection_start(self, indicator): 143 if self.soft_space: 144 self.writer.write(" ") 145 self.writer.write(indicator) 146 self.soft_space = False 147 148 def write_collection_end(self, indicator): 149 self.writer.write(indicator) 150 self.soft_space = True 312 if not self.line: 313 self.write_line_break() 314 self.writer.write("...") 315 self.write_line_break() 316 317 def write_line_break(self): 318 self.writer.write('\n') 319 self.space = True 320 self.line = True 151 321 152 322 def write_anchor(self, indicator, name): 153 if self.soft_space:323 if not self.space: 154 324 self.writer.write(" ") 155 325 self.writer.write("%s%s" % (indicator, name)) 156 self.soft_space = True 326 self.space = False 327 self.line = False 157 328 158 329 def write_tag(self, tag): 159 if self.soft_space:330 if not self.space: 160 331 self.writer.write(" ") 161 332 if tag.startswith("tag:yaml.org,2002:"): … … 163 334 else: 164 335 self.writer.write("!<%s>" % tag) 165 self.soft_space = True 166 167 def write_scalar(self, value): 168 if self.soft_space: 336 self.space = False 337 self.line = False 338 339 def is_simple(self, event): 340 if not isinstance(event, ScalarEvent): 341 return False 342 if '\n' in event.value or len(event.value) > 128: 343 return False 344 if event.style and event.style in '|>': 345 return False 346 return True 347 348 def write_scalar(self, value, implicit, style): 349 if implicit: 350 if not self.space: 351 self.writer.write(" ") 352 self.writer.write(value.encode('utf-8')) 353 self.space = False 354 self.line = False 355 elif style in ['>', '|'] and not self.flow_level and not self.simple_key: 356 if not self.space: 357 self.writer.write(" ") 358 self.writer.write("|-") 359 self.write_line_break() 360 self.write_indent() 361 self.writer.write(value.encode('utf-8')) 362 self.write_line_break() 363 else: 364 if not self.space: 365 self.writer.write(" ") 366 self.writer.write("\"%s\"" % value.encode('utf-8')) 367 self.space = False 368 self.line = False 369 370 def write_indicator(self, indicator, need_space=False, provide_space=False): 371 if need_space and not self.space: 169 372 self.writer.write(" ") 170 self.writer.write("\"%s\"" % value.encode('utf-8'))171 self.soft_space = True172 173 def write_indicator(self, indicator):174 373 self.writer.write(indicator) 175 self.soft_space = True 374 self.space = provide_space 375 self.line = False 176 376 177 377 def write_indent(self): 178 self.writer.write("\n"+" "*(self.level*2)) 179 self.soft_space = False 180 378 if not self.line: 379 self.write_line_break() 380 if self.indent: 381 self.writer.write(" "*self.indent) 382 self.line = False 383 self.space = True 384 -
pyyaml/branches/working-on-emitter/tests/test_emitter.py
r127 r129 3 3 4 4 from yaml import * 5 import yaml 5 6 6 7 class TestEmitterOnCanonical(test_appliance.TestAppliance): … … 16 17 for event in events: 17 18 emitter.emit(event) 19 data = writer.getvalue() 20 new_events = list(parse(data)) 21 self.failUnlessEqual(len(events), len(new_events)) 22 for event, new_event in zip(events, new_events): 23 self.failUnlessEqual(event.__class__, new_event.__class__) 18 24 19 25 TestEmitterOnCanonical.add_tests('testEmitterOnCanonical', '.canonical') 20 26 27 class EventsConstructor(Constructor): 28 29 def construct_event(self, node): 30 if isinstance(node, ScalarNode): 31 mapping = {} 32 else: 33 mapping = self.construct_mapping(node) 34 class_name = str(node.tag[1:])+'Event' 35 if class_name in ['AliasEvent', 'ScalarEvent', 'SequenceEvent', 'MappingEvent']: 36 mapping.setdefault('anchor', None) 37 if class_name in ['ScalarEvent', 'SequenceEvent', 'MappingEvent']: 38 mapping.setdefault('tag', None) 39 if class_name == 'ScalarEvent': 40 mapping.setdefault('value', '') 41 value = getattr(yaml, class_name)(**mapping) 42 return value 43 44 EventsConstructor.add_constructor(None, EventsConstructor.construct_event) 45 46 class TestEmitter(test_appliance.TestAppliance): 47 48 def _testEmitter(self, test_name, events_filename): 49 events = load_document(file(events_filename, 'rb'), Constructor=EventsConstructor) 50 self._dump(events_filename, events) 51 writer = StringIO.StringIO() 52 emitter = Emitter(writer) 53 for event in events: 54 emitter.emit(event) 55 data = writer.getvalue() 56 new_events = list(parse(data)) 57 self.failUnlessEqual(len(events), len(new_events)) 58 for event, new_event in zip(events, new_events): 59 self.failUnlessEqual(event.__class__, new_event.__class__) 60 61 def _dump(self, events_filename, events): 62 writer = sys.stdout 63 emitter = Emitter(writer) 64 print "="*30 65 print "EVENTS:" 66 print file(events_filename, 'rb').read() 67 print '-'*30 68 print "OUTPUT:" 69 for event in events: 70 emitter.emit(event) 71 72 TestEmitter.add_tests('testEmitter', '.events') 73
Note: See TracChangeset
for help on using the changeset viewer.
