Changeset 137
- Timestamp:
- 04/16/06 19:45:21 (7 years ago)
- Location:
- pyyaml/trunk
- Files:
-
- 2 added
- 18 edited
- 2 moved
-
lib/yaml/__init__.py (modified) (5 diffs)
-
lib/yaml/composer.py (modified) (10 diffs)
-
lib/yaml/dumper.py (modified) (4 diffs)
-
lib/yaml/emitter.py (modified) (2 diffs)
-
lib/yaml/events.py (modified) (2 diffs)
-
lib/yaml/loader.py (modified) (4 diffs)
-
lib/yaml/parser.py (modified) (4 diffs)
-
lib/yaml/representer.py (modified) (1 diff)
-
lib/yaml/resolver.py (moved) (moved from pyyaml/trunk/lib/yaml/detector.py) (7 diffs)
-
lib/yaml/serializer.py (modified) (3 diffs)
-
lib/yaml/tokens.py (modified) (1 diff)
-
tests/data/documents.events (modified) (1 diff)
-
tests/data/mappings.events (modified) (1 diff)
-
tests/data/resolver.data (added)
-
tests/data/resolver.path (added)
-
tests/data/scalars.events (modified) (1 diff)
-
tests/data/sequences.events (modified) (6 diffs)
-
tests/data/sloppy-indentation.canonical (modified) (1 diff)
-
tests/test_appliance.py (modified) (3 diffs)
-
tests/test_emitter.py (modified) (2 diffs)
-
tests/test_resolver.py (moved) (moved from pyyaml/trunk/tests/test_detector.py) (2 diffs)
-
tests/test_yaml.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
pyyaml/trunk/lib/yaml/__init__.py
r136 r137 12 12 from representer import * 13 13 14 from detector import *14 from resolver import * 15 15 16 16 from tokens import * … … 197 197 return dump_all([data], stream, Dumper=SafeDumper, **kwds) 198 198 199 def add_detector(tag, regexp, first=None, Loader=Loader, Dumper=Dumper): 199 def add_implicit_detector(tag, regexp, first=None, 200 Loader=Loader, Dumper=Dumper): 200 201 """ 201 202 Add an implicit scalar detector. … … 204 205 first is a sequence of possible initial characters or None. 205 206 """ 206 Loader.add_ detector(tag, regexp, first)207 Dumper.add_ detector(tag, regexp, first)208 209 def add_ resolver(tag, path, Loader=Loader):207 Loader.add_implicit_resolver(tag, regexp, first) 208 Dumper.add_implicit_resolver(tag, regexp, first) 209 210 def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper): 210 211 """ 211 212 Add a path based resolver for the given tag. … … 214 215 Keys can be string values, integers, or None. 215 216 """ 216 Loader.add_resolver(tag, path) 217 Loader.add_path_resolver(tag, path, kind) 218 Dumper.add_path_resolver(tag, path, kind) 217 219 218 220 def add_constructor(tag, constructor, Loader=Loader): … … 232 234 """ 233 235 Loader.add_multi_constructor(tag_prefix, multi_constructor) 236 237 def add_representer(data_type, representer, Dumper=Dumper): 238 """ 239 Add a representer for the given type. 240 Representer is a function accepting a Dumper instance 241 and an instance of the given data type 242 and producing the corresponding representation node. 243 """ 244 Dumper.add_representer(data_type, representer) 234 245 235 246 class YAMLObjectMetaclass(type): -
pyyaml/trunk/lib/yaml/composer.py
r136 r137 1 1 2 __all__ = [' BaseComposer', 'Composer', 'ComposerError']2 __all__ = ['Composer', 'ComposerError'] 3 3 4 4 from error import MarkedYAMLError … … 9 9 pass 10 10 11 class BaseComposer: 12 13 yaml_resolvers = {} 11 class Composer: 14 12 15 13 def __init__(self): 16 14 self.all_anchors = {} 17 15 self.complete_anchors = {} 18 self.resolver_tags = []19 self.resolver_paths = []20 16 21 17 def check_node(self): … … 43 39 44 40 # Compose the root node. 45 node = self.compose_node( [])41 node = self.compose_node(None, None) 46 42 47 43 # Drop the DOCUMENT-END event. … … 50 46 self.all_anchors = {} 51 47 self.complete_anchors = {} 52 self.resolver_tags = []53 self.resolver_paths = []54 48 return node 55 49 56 def increase_resolver_depth(self, path): 57 depth = len(path) 58 tag = None 59 paths = [] 60 if not depth: 61 for resolver_path in self.yaml_resolvers.keys(): 62 if resolver_path: 63 paths.append(resolver_path) 64 else: 65 tag = self.yaml_resolvers[resolver_path] 66 else: 67 base, index = path[-1] 68 if isinstance(index, ScalarNode) \ 69 and index.tag == self.DEFAULT_SCALAR_TAG: 70 index = index.value 71 elif isinstance(index, Node): 72 index = None 73 for resolver_path in self.resolver_paths[-1]: 74 resolver_index = resolver_path[depth-1] 75 if resolver_index is None or resolver_index == index: 76 if len(resolver_index) > depth: 77 paths.append(resolver_path) 78 else: 79 tag = self.yaml_resolvers[resolver_path] 80 self.resolver_tags.append(tag) 81 self.resolver_paths.append(paths) 82 83 def decrease_resolver_depth(self): 84 del self.resolver_tags[-1] 85 del self.resolver_paths[-1] 86 87 def compose_node(self, path): 50 def compose_node(self, parent, index): 88 51 if self.check_event(AliasEvent): 89 52 event = self.get_event() … … 99 62 event.start_mark) 100 63 return self.complete_anchors[anchor] 101 self.increase_resolver_depth(path)102 64 event = self.peek_event() 103 65 anchor = event.anchor … … 108 70 "second occurence", event.start_mark) 109 71 self.all_anchors[anchor] = event 72 self.descend_resolver(parent, index) 110 73 if self.check_event(ScalarEvent): 111 node = self.compose_scalar_node( path)74 node = self.compose_scalar_node() 112 75 elif self.check_event(SequenceStartEvent): 113 node = self.compose_sequence_node( path)76 node = self.compose_sequence_node() 114 77 elif self.check_event(MappingStartEvent): 115 node = self.compose_mapping_node( path)78 node = self.compose_mapping_node() 116 79 if anchor is not None: 117 80 self.complete_anchors[anchor] = node 118 self. decrease_resolver_depth()81 self.ascend_resolver() 119 82 return node 120 83 121 def compose_scalar_node(self , path):84 def compose_scalar_node(self): 122 85 event = self.get_event() 123 tag = self.resolve_scalar(path, event.tag, event.implicit, event.value) 86 tag = event.tag 87 if tag is None or tag == u'!': 88 tag = self.resolve(ScalarNode, event.value, event.implicit) 124 89 return ScalarNode(tag, event.value, 125 90 event.start_mark, event.end_mark, style=event.style) 126 91 127 def compose_sequence_node(self , path):92 def compose_sequence_node(self): 128 93 start_event = self.get_event() 129 tag = self.resolve_sequence(path, start_event.tag) 94 tag = start_event.tag 95 if tag is None or tag == u'!': 96 tag = self.resolve(SequenceNode, None, start_event.implicit) 130 97 node = SequenceNode(tag, [], 131 98 start_event.start_mark, None, … … 133 100 index = 0 134 101 while not self.check_event(SequenceEndEvent): 135 node.value.append(self.compose_node( path+[(node, index)]))102 node.value.append(self.compose_node(node, index)) 136 103 index += 1 137 104 end_event = self.get_event() … … 139 106 return node 140 107 141 def compose_mapping_node(self , path):108 def compose_mapping_node(self): 142 109 start_event = self.get_event() 143 tag = self.resolve_mapping(path, start_event.tag) 110 tag = start_event.tag 111 if tag is None or tag == u'!': 112 tag = self.resolve(MappingNode, None, start_event.implicit) 144 113 node = MappingNode(tag, {}, 145 114 start_event.start_mark, None, … … 147 116 while not self.check_event(MappingEndEvent): 148 117 key_event = self.peek_event() 149 item_key = self.compose_node(path+[(node, None)]) 150 item_value = self.compose_node(path+[(node, item_key)]) 118 item_key = self.compose_node(node, None) 151 119 if item_key in node.value: 152 120 raise ComposerError("while composing a mapping", start_event.start_mark, 153 121 "found duplicate key", key_event.start_mark) 122 item_value = self.compose_node(node, item_key) 154 123 node.value[item_key] = item_value 155 124 end_event = self.get_event() … … 157 126 return node 158 127 159 def resolve_scalar(self, path, tag, implicit, value):160 if implicit:161 tag = self.detect(value)162 if tag is None and self.resolver_tags[-1]:163 tag = self.resolver_tags[-1]164 if tag is None or tag == u'!':165 tag = self.DEFAULT_SCALAR_TAG166 return tag167 168 def resolve_sequence(self, path, tag):169 if tag is None and self.resolver_tags[-1]:170 tag = self.resolver_tags[-1]171 if tag is None or tag == u'!':172 tag = self.DEFAULT_SEQUENCE_TAG173 return tag174 175 def resolve_mapping(self, path, tag):176 if tag is None and self.resolver_tags[-1]:177 tag = self.resolver_tags[-1]178 if tag is None or tag == u'!':179 tag = self.DEFAULT_MAPPING_TAG180 return tag181 182 def add_resolver(self, tag, path):183 if not 'yaml_resolvers' in cls.__dict__:184 cls.yaml_resolvers = cls.yaml_resolvers.copy()185 cls.yaml_resolvers[tuple(path)] = tag186 add_resolver = classmethod(add_resolver)187 188 class Composer(BaseComposer):189 pass190 -
pyyaml/trunk/lib/yaml/dumper.py
r136 r137 5 5 from serializer import * 6 6 from representer import * 7 from detector import *7 from resolver import * 8 8 9 class BaseDumper(Emitter, Serializer, BaseRepresenter, Base Detector):9 class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver): 10 10 11 11 def __init__(self, stream, … … 21 21 version=version, tags=tags) 22 22 Representer.__init__(self) 23 Detector.__init__(self)23 Resolver.__init__(self) 24 24 25 class SafeDumper(Emitter, Serializer, SafeRepresenter, Detector):25 class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver): 26 26 27 27 def __init__(self, stream, … … 37 37 version=version, tags=tags) 38 38 SafeRepresenter.__init__(self) 39 Detector.__init__(self)39 Resolver.__init__(self) 40 40 41 class Dumper(Emitter, Serializer, Representer, Detector):41 class Dumper(Emitter, Serializer, Representer, Resolver): 42 42 43 43 def __init__(self, stream, … … 53 53 version=version, tags=tags) 54 54 Representer.__init__(self) 55 Detector.__init__(self)55 Resolver.__init__(self) 56 56 -
pyyaml/trunk/lib/yaml/emitter.py
r136 r137 461 461 if self.style is None: 462 462 self.style = self.choose_scalar_style() 463 if self.style == '': 463 if ((not self.canonical or tag is None) and 464 ((self.style == '' and self.event.implicit[0]) 465 or (self.style != '' and self.event.implicit[1]))): 464 466 self.prepared_tag = None 465 467 return 466 if self.event.implicit and not tag:468 if self.event.implicit[0] and not tag: 467 469 tag = u'!' 468 470 self.prepared_tag = None 471 else: 472 if (not self.canonical or tag is None) and self.event.implicit: 473 self.prepared_tag = None 474 return 469 475 if not tag: 470 self.prepared_tag = None 471 return 476 raise EmitterError("tag is not specified") 472 477 if self.prepared_tag is None: 473 478 self.prepared_tag = self.prepare_tag(tag) … … 481 486 if self.event.style == '"' or self.canonical: 482 487 return '"' 483 if not self.event.style and self.event.implicit :488 if not self.event.style and self.event.implicit[0]: 484 489 if (not (self.simple_key_context and 485 490 (self.analysis.empty or self.analysis.multiline)) -
pyyaml/trunk/lib/yaml/events.py
r136 r137 7 7 self.end_mark = end_mark 8 8 def __repr__(self): 9 attributes = [key for key in ['anchor', 'tag', ' value']9 attributes = [key for key in ['anchor', 'tag', 'implicit', 'value'] 10 10 if hasattr(self, key)] 11 11 arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) … … 20 20 21 21 class CollectionStartEvent(NodeEvent): 22 def __init__(self, anchor, tag, start_mark=None, end_mark=None,22 def __init__(self, anchor, tag, implicit, start_mark=None, end_mark=None, 23 23 flow_style=None): 24 24 self.anchor = anchor 25 25 self.tag = tag 26 self.implicit = implicit 26 27 self.start_mark = start_mark 27 28 self.end_mark = end_mark -
pyyaml/trunk/lib/yaml/loader.py
r136 r137 7 7 from composer import * 8 8 from constructor import * 9 from detector import *9 from resolver import * 10 10 11 class BaseLoader(Reader, Scanner, Parser, 12 BaseComposer, BaseConstructor, BaseDetector): 11 class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver): 13 12 14 13 def __init__(self, stream): … … 16 15 Scanner.__init__(self) 17 16 Parser.__init__(self) 18 BaseComposer.__init__(self)17 Composer.__init__(self) 19 18 BaseConstructor.__init__(self) 20 Base Detector.__init__(self)19 BaseResolver.__init__(self) 21 20 22 class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Detector):21 class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver): 23 22 24 23 def __init__(self, stream): … … 28 27 Composer.__init__(self) 29 28 SafeConstructor.__init__(self) 30 Detector.__init__(self)29 Resolver.__init__(self) 31 30 32 class Loader(Reader, Scanner, Parser, Composer, Constructor, Detector):31 class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver): 33 32 34 33 def __init__(self, stream): … … 38 37 Composer.__init__(self) 39 38 Constructor.__init__(self) 40 Detector.__init__(self)39 Resolver.__init__(self) 41 40 -
pyyaml/trunk/lib/yaml/parser.py
r136 r137 267 267 event = None 268 268 collection_events = None 269 implicit = (tag is None or tag == u'!') 269 270 if indentless_sequence and self.check_token(BlockEntryToken): 270 271 end_mark = self.peek_token().end_mark 271 event = SequenceStartEvent(anchor, tag, start_mark, end_mark) 272 event = SequenceStartEvent(anchor, tag, implicit, 273 start_mark, end_mark) 272 274 collection_events = self.parse_indentless_sequence() 273 275 else: … … 275 277 token = self.get_token() 276 278 end_mark = token.end_mark 277 implicit = ((tag is None or tag == u'!') and token.implicit) 279 if (token.plain and tag is None) or tag == u'!': 280 implicit = (True, False) 281 elif tag is None: 282 implicit = (False, True) 283 else: 284 implicit = (False, False) 278 285 event = ScalarEvent(anchor, tag, implicit, token.value, 279 286 start_mark, end_mark, style=token.style) 280 287 elif self.check_token(FlowSequenceStartToken): 281 288 end_mark = self.peek_token().end_mark 282 event = SequenceStartEvent(anchor, tag, start_mark, end_mark,283 flow_style=True)289 event = SequenceStartEvent(anchor, tag, implicit, 290 start_mark, end_mark, flow_style=True) 284 291 collection_events = self.parse_flow_sequence() 285 292 elif self.check_token(FlowMappingStartToken): 286 293 end_mark = self.peek_token().end_mark 287 event = MappingStartEvent(anchor, tag, start_mark, end_mark,288 flow_style=True)294 event = MappingStartEvent(anchor, tag, implicit, 295 start_mark, end_mark, flow_style=True) 289 296 collection_events = self.parse_flow_mapping() 290 297 elif block and self.check_token(BlockSequenceStartToken): 291 298 end_mark = self.peek_token().start_mark 292 event = SequenceStartEvent(anchor, tag, start_mark, end_mark,293 flow_style=False)299 event = SequenceStartEvent(anchor, tag, implicit, 300 start_mark, end_mark, flow_style=False) 294 301 collection_events = self.parse_block_sequence() 295 302 elif block and self.check_token(BlockMappingStartToken): 296 303 end_mark = self.peek_token().start_mark 297 event = MappingStartEvent(anchor, tag, start_mark, end_mark,298 flow_style=False)304 event = MappingStartEvent(anchor, tag, implicit, 305 start_mark, end_mark, flow_style=False) 299 306 collection_events = self.parse_block_mapping() 300 307 elif anchor is not None or tag is not None: 301 308 # Empty scalars are allowed even if a tag or an anchor is 302 309 # specified. 303 implicit = (tag is None or tag == u'!') 304 event = ScalarEvent(anchor, tag, implicit, u'', 310 event = ScalarEvent(anchor, tag, (implicit, False), u'', 305 311 start_mark, end_mark) 306 312 else: … … 397 403 if self.check_token(KeyToken): 398 404 token = self.get_token() 399 yield MappingStartEvent(None, None, # u'!',405 yield MappingStartEvent(None, None, True, 400 406 token.start_mark, token.end_mark, 401 407 flow_style=True) … … 475 481 476 482 def process_empty_scalar(self, mark): 477 return ScalarEvent(None, None, True, u'', mark, mark)478 483 return ScalarEvent(None, None, (True, False), u'', mark, mark) 484 -
pyyaml/trunk/lib/yaml/representer.py
r136 r137 5 5 from error import * 6 6 from nodes import * 7 from detector import *8 7 9 8 try: -
pyyaml/trunk/lib/yaml/resolver.py
r136 r137 1 1 2 __all__ = ['BaseDetector', 'Detector'] 2 __all__ = ['BaseResolver', 'Resolver'] 3 4 from error import * 5 from nodes import * 3 6 4 7 import re 5 8 6 class BaseDetector: 9 class ResolverError(YAMLError): 10 pass 11 12 class BaseResolver: 7 13 8 14 DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str' … … 10 16 DEFAULT_MAPPING_TAG = u'tag:yaml.org,2002:map' 11 17 12 yaml_detectors = {} 18 yaml_implicit_resolvers = {} 19 yaml_path_resolvers = {} 13 20 14 21 def __init__(self): 15 pass 16 17 def add_detector(cls, tag, regexp, first): 18 if not 'yaml_detectors' in cls.__dict__: 19 cls.yaml_detectors = cls.yaml_detectors.copy() 22 self.resolver_exact_paths = [] 23 self.resolver_prefix_paths = [] 24 25 def add_implicit_resolver(cls, tag, regexp, first): 26 if not 'yaml_implicit_resolvers' in cls.__dict__: 27 cls.yaml_implicit_resolvers = cls.yaml_implicit_resolvers.copy() 20 28 for ch in first: 21 cls.yaml_detectors.setdefault(ch, []).append((tag, regexp)) 22 add_detector = classmethod(add_detector) 23 24 def detect(self, value): 25 if value == u'': 26 detectors = self.yaml_detectors.get(u'', []) 29 cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp)) 30 add_implicit_resolver = classmethod(add_implicit_resolver) 31 32 def add_path_resolver(cls, tag, path, kind=None): 33 if not 'yaml_path_resolvers' in cls.__dict__: 34 cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy() 35 new_path = [] 36 for element in path: 37 if isinstance(element, (list, tuple)): 38 if len(element) == 2: 39 node_check, index_check = element 40 elif len(element) == 1: 41 node_check = element[0] 42 index_check = True 43 else: 44 raise ResolverError("Invalid path element: %s" % element) 45 else: 46 node_check = None 47 index_check = element 48 if node_check is str: 49 node_check = ScalarNode 50 elif node_check is list: 51 node_check = SequenceNode 52 elif node_check is map: 53 node_check = MappingNode 54 elif node_check not in [ScalarNode, SequenceNode, MappingNode] \ 55 and not isinstance(node_check, basestring) \ 56 and node_check is not None: 57 raise ResolverError("Invalid node checker: %s" % node_check) 58 if not isinstance(index_check, (basestring, int)) \ 59 and index_check is not None: 60 raise ResolverError("Invalid index checker: %s" % index_check) 61 new_path.append((node_check, index_check)) 62 if kind is str: 63 kind = ScalarNode 64 elif kind is list: 65 kind = SequenceNode 66 elif kind is map: 67 kind = MappingNode 68 elif kind not in [ScalarNode, SequenceNode, MappingNode] \ 69 and kind is not None: 70 raise ResolverError("Invalid node kind: %s" % kind) 71 cls.yaml_path_resolvers[tuple(new_path), kind] = tag 72 add_path_resolver = classmethod(add_path_resolver) 73 74 def descend_resolver(self, current_node, current_index): 75 exact_paths = {} 76 prefix_paths = [] 77 if current_node: 78 depth = len(self.resolver_prefix_paths) 79 for path, kind in self.resolver_prefix_paths[-1]: 80 if self.check_resolver_prefix(depth, path, kind, 81 current_node, current_index): 82 if len(path) > depth: 83 prefix_paths.append((path, kind)) 84 else: 85 exact_paths[kind] = self.yaml_path_resolvers[path, kind] 27 86 else: 28 detectors = self.yaml_detectors.get(value[0], []) 29 detectors += self.yaml_detectors.get(None, []) 30 for tag, regexp in detectors: 31 if regexp.match(value): 32 return tag 33 34 class Detector(BaseDetector): 87 for path, kind in self.yaml_path_resolvers: 88 if not path: 89 exact_paths[kind] = self.yaml_path_resolvers[path, kind] 90 else: 91 prefix_paths.append((path, kind)) 92 self.resolver_exact_paths.append(exact_paths) 93 self.resolver_prefix_paths.append(prefix_paths) 94 95 def ascend_resolver(self): 96 self.resolver_exact_paths.pop() 97 self.resolver_prefix_paths.pop() 98 99 def check_resolver_prefix(self, depth, path, kind, 100 current_node, current_index): 101 node_check, index_check = path[depth-1] 102 if isinstance(node_check, basestring): 103 if current_node.tag != node_check: 104 return 105 elif node_check is not None: 106 if not isinstance(current_node, node_check): 107 return 108 if index_check is True and current_index is not None: 109 return 110 if index_check in [False, None] and current_index is None: 111 return 112 if isinstance(index_check, basestring): 113 if not (isinstance(current_index, ScalarNode) 114 and index_check == current_index.value): 115 return 116 elif isinstance(index_check, int): 117 if index_check != current_index: 118 return 119 return True 120 121 def resolve(self, kind, value, implicit): 122 if kind is ScalarNode and implicit[0]: 123 if value == u'': 124 resolvers = self.yaml_implicit_resolvers.get(u'', []) 125 else: 126 resolvers = self.yaml_implicit_resolvers.get(value[0], []) 127 resolvers += self.yaml_implicit_resolvers.get(None, []) 128 for tag, regexp in resolvers: 129 if regexp.match(value): 130 return tag 131 implicit = implicit[1] 132 exact_paths = self.resolver_exact_paths[-1] 133 if kind in exact_paths: 134 return exact_paths[kind] 135 if None in exact_paths: 136 return exact_paths[None] 137 if kind is ScalarNode: 138 return self.DEFAULT_SCALAR_TAG 139 elif kind is SequenceNode: 140 return self.DEFAULT_SEQUENCE_TAG 141 elif kind is MappingNode: 142 return self.DEFAULT_MAPPING_TAG 143 144 class Resolver(BaseResolver): 35 145 pass 36 146 37 Detector.add_detector(147 Resolver.add_implicit_resolver( 38 148 u'tag:yaml.org,2002:bool', 39 149 re.compile(ur'''^(?:yes|Yes|YES|n|N|no|No|NO … … 42 152 list(u'yYnNtTfFoO')) 43 153 44 Detector.add_detector(154 Resolver.add_implicit_resolver( 45 155 u'tag:yaml.org,2002:float', 46 156 re.compile(ur'''^(?:[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*(?:[eE][-+][0-9]+)? … … 50 160 list(u'-+0123456789.')) 51 161 52 Detector.add_detector(162 Resolver.add_implicit_resolver( 53 163 u'tag:yaml.org,2002:int', 54 164 re.compile(ur'''^(?:[-+]?0b[0-1_]+ … … 59 169 list(u'-+0123456789')) 60 170 61 Detector.add_detector(171 Resolver.add_implicit_resolver( 62 172 u'tag:yaml.org,2002:merge', 63 173 re.compile(ur'^(?:<<)$'), 64 174 ['<']) 65 175 66 Detector.add_detector(176 Resolver.add_implicit_resolver( 67 177 u'tag:yaml.org,2002:null', 68 178 re.compile(ur'''^(?: ~ … … 71 181 [u'~', u'n', u'N', u'']) 72 182 73 Detector.add_detector(183 Resolver.add_implicit_resolver( 74 184 u'tag:yaml.org,2002:timestamp', 75 185 re.compile(ur'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] … … 80 190 list(u'0123456789')) 81 191 82 Detector.add_detector(192 Resolver.add_implicit_resolver( 83 193 u'tag:yaml.org,2002:value', 84 194 re.compile(ur'^(?:=)$'), 85 195 ['=']) 86 196 87 # The following detector is only for documentation purposes. It cannot work197 # The following resolver is only for documentation purposes. It cannot work 88 198 # because plain scalars cannot start with '!', '&', or '*'. 89 Detector.add_detector(199 Resolver.add_implicit_resolver( 90 200 u'tag:yaml.org,2002:yaml', 91 201 re.compile(ur'^(?:!|&|\*)$'), -
pyyaml/trunk/lib/yaml/serializer.py
r136 r137 52 52 version=self.use_version, tags=self.use_tags)) 53 53 self.anchor_node(node) 54 self.serialize_node(node )54 self.serialize_node(node, None, None) 55 55 self.emit(DocumentEndEvent(explicit=self.use_explicit_end)) 56 56 self.serialized_nodes = {} … … 76 76 return self.ANCHOR_TEMPLATE % self.last_anchor_id 77 77 78 def serialize_node(self, node ):78 def serialize_node(self, node, parent, index): 79 79 alias = self.anchors[node] 80 80 if node in self.serialized_nodes: … … 82 82 else: 83 83 self.serialized_nodes[node] = True 84 self.descend_resolver(parent, index) 84 85 if isinstance(node, ScalarNode): 85 detected_tag = self.detect(node.value) 86 implicit = (node.tag == self.detect(node.value) 87 or (node.tag == self.DEFAULT_SCALAR_TAG 88 and detected_tag is None)) 86 detected_tag = self.resolve(ScalarNode, node.value, (True, False)) 87 default_tag = self.resolve(ScalarNode, node.value, (False, True)) 88 implicit = (node.tag == detected_tag), (node.tag == default_tag) 89 89 self.emit(ScalarEvent(alias, node.tag, implicit, node.value, 90 90 style=node.style)) 91 91 elif isinstance(node, SequenceNode): 92 # TODO: 93 # 1) Check the current path in the Resolver. 94 # 2) Add the implicit flag to the SequenceStartEvent and 95 # MappingStartEvent. 96 tag = node.tag 97 if tag == self.DEFAULT_SEQUENCE_TAG and not self.canonical: 98 tag = None 99 self.emit(SequenceStartEvent(alias, tag, 92 implicit = (node.tag 93 == self.resolve(SequenceNode, node.value, True)) 94 self.emit(SequenceStartEvent(alias, node.tag, implicit, 100 95 flow_style=node.flow_style)) 96 index = 0 101 97 for item in node.value: 102 self.serialize_node(item) 98 self.serialize_node(item, node, index) 99 index += 1 103 100 self.emit(SequenceEndEvent()) 104 101 elif isinstance(node, MappingNode): 105 tag = node.tag 106 if tag == self.DEFAULT_MAPPING_TAG and not self.canonical: 107 tag = None 108 self.emit(MappingStartEvent(alias, tag, 102 implicit = (node.tag 103 == self.resolve(MappingNode, node.value, True)) 104 self.emit(MappingStartEvent(alias, node.tag, implicit, 109 105 flow_style=node.flow_style)) 110 106 if hasattr(node.value, 'keys'): 111 107 for key in node.value.keys(): 112 self.serialize_node(key )113 self.serialize_node(node.value[key] )108 self.serialize_node(key, node, None) 109 self.serialize_node(node.value[key], node, key) 114 110 else: 115 111 for key, value in node.value: 116 self.serialize_node(key )117 self.serialize_node(value )112 self.serialize_node(key, node, None) 113 self.serialize_node(value, node, key) 118 114 self.emit(MappingEndEvent()) 115 self.ascend_resolver() 119 116 -
pyyaml/trunk/lib/yaml/tokens.py
r130 r137 96 96 class ScalarToken(Token): 97 97 id = '<scalar>' 98 def __init__(self, value, implicit, start_mark, end_mark, style=None):98 def __init__(self, value, plain, start_mark, end_mark, style=None): 99 99 self.value = value 100 self. implicit = implicit100 self.plain = plain 101 101 self.start_mark = start_mark 102 102 self.end_mark = end_mark -
pyyaml/trunk/tests/data/documents.events
r132 r137 1 1 - !StreamStart 2 2 - !DocumentStart { explicit: false } 3 - !Scalar { implicit: true, value: 'data' }3 - !Scalar { implicit: [true,false], value: 'data' } 4 4 - !DocumentEnd 5 5 - !DocumentStart 6 - !Scalar { implicit: true}6 - !Scalar { implicit: [true,false] } 7 7 - !DocumentEnd 8 8 - !DocumentStart { version: [1,1], tags: { '!': '!foo', '!yaml!': 'tag:yaml.org,2002:', '!ugly!': '!!!!!!!' } } 9 - !Scalar { implicit: true}9 - !Scalar { implicit: [true,false] } 10 10 - !DocumentEnd 11 11 - !StreamEnd -
pyyaml/trunk/tests/data/mappings.events
r132 r137 3 3 - !DocumentStart 4 4 - !MappingStart 5 - !Scalar { implicit: true, value: 'key' }6 - !Scalar { implicit: true, value: 'value' }7 - !Scalar { implicit: true, value: 'empty mapping' }5 - !Scalar { implicit: [true,true], value: 'key' } 6 - !Scalar { implicit: [true,true], value: 'value' } 7 - !Scalar { implicit: [true,true], value: 'empty mapping' } 8 8 - !MappingStart 9 9 - !MappingEnd 10 - !Scalar { implicit: true, value: 'empty mapping with tag' }11 - !MappingStart { tag: '!mytag' }10 - !Scalar { implicit: [true,true], value: 'empty mapping with tag' } 11 - !MappingStart { tag: '!mytag', implicit: false } 12 12 - !MappingEnd 13 - !Scalar { implicit: true, value: 'block mapping' }13 - !Scalar { implicit: [true,true], value: 'block mapping' } 14 14 - !MappingStart 15 15 - !MappingStart 16 - !Scalar { implicit: true, value: 'complex' }17 - !Scalar { implicit: true, value: 'key' }18 - !Scalar { implicit: true, value: 'complex' }19 - !Scalar { implicit: true, value: 'key' }16 - !Scalar { implicit: [true,true], value: 'complex' } 17 - !Scalar { implicit: [true,true], value: 'key' } 18 - !Scalar { implicit: [true,true], value: 'complex' } 19 - !Scalar { implicit: [true,true], value: 'key' } 20 20 - !MappingEnd 21 21 - !MappingStart 22 - !Scalar { implicit: true, value: 'complex' }23 - !Scalar { implicit: true, value: 'key' }22 - !Scalar { implicit: [true,true], value: 'complex' } 23 - !Scalar { implicit: [true,true], value: 'key' } 24 24 - !MappingEnd 25 25 - !MappingEnd 26 - !Scalar { implicit: true, value: 'flow mapping' }26 - !Scalar { implicit: [true,true], value: 'flow mapping' } 27 27 - !MappingStart { flow_style: true } 28 - !Scalar { implicit: true, value: 'key' }29 - !Scalar { implicit: true, value: 'value' }28 - !Scalar { implicit: [true,true], value: 'key' } 29 - !Scalar { implicit: [true,true], value: 'value' } 30 30 - !MappingStart 31 - !Scalar { implicit: true, value: 'complex' }32 - !Scalar { implicit: true, value: 'key' }33 - !Scalar { implicit: true, value: 'complex' }34 - !Scalar { implicit: true, value: 'key' }31 - !Scalar { implicit: [true,true], value: 'complex' } 32 - !Scalar { implicit: [true,true], value: 'key' } 33 - !Scalar { implicit: [true,true], value: 'complex' } 34 - !Scalar { implicit: [true,true], value: 'key' } 35 35 - !MappingEnd 36 36 - !MappingStart 37 - !Scalar { implicit: true, value: 'complex' }38 - !Scalar { implicit: true, value: 'key' }37 - !Scalar { implicit: [true,true], value: 'complex' } 38 - !Scalar { implicit: [true,true], value: 'key' } 39 39 - !MappingEnd 40 40 - !MappingEnd -
pyyaml/trunk/tests/data/scalars.events
r133 r137 3 3 - !DocumentStart 4 4 - !MappingStart 5 - !Scalar { implicit: true, value: 'empty scalar' }6 - !Scalar { implicit: true, value: '' }7 - !Scalar { implicit: true, value: 'implicit scalar' }8 - !Scalar { implicit: true, value: 'data' }9 - !Scalar { implicit: true, value: 'quoted scalar' }5 - !Scalar { implicit: [true,true], value: 'empty scalar' } 6 - !Scalar { implicit: [true,false], value: '' } 7 - !Scalar { implicit: [true,true], value: 'implicit scalar' } 8 - !Scalar { implicit: [true,true], value: 'data' } 9 - !Scalar { implicit: [true,true], value: 'quoted scalar' } 10 10 - !Scalar { value: 'data', style: '"' } 11 - !Scalar { implicit: true, value: 'block scalar' }11 - !Scalar { implicit: [true,true], value: 'block scalar' } 12 12 - !Scalar { value: 'data', style: '|' } 13 - !Scalar { implicit: true, value: 'empty scalar with tag' }14 - !Scalar { implicit: true, tag: '!mytag', value: '' }15 - !Scalar { implicit: true, value: 'implicit scalar with tag' }16 - !Scalar { implicit: true, tag: '!mytag', value: 'data' }17 - !Scalar { implicit: true, value: 'quoted scalar with tag' }18 - !Scalar { value: 'data', style: '"', tag: '!mytag' }19 - !Scalar { implicit: true, value: 'block scalar with tag' }20 - !Scalar { value: 'data', style: '|', tag: '!mytag' }21 - !Scalar { implicit: true, value: 'single character' }22 - !Scalar { value: 'a', implicit: true}23 - !Scalar { implicit: true, value: 'single digit' }24 - !Scalar { value: '1', implicit: true}13 - !Scalar { implicit: [true,true], value: 'empty scalar with tag' } 14 - !Scalar { implicit: [false,false], tag: '!mytag', value: '' } 15 - !Scalar { implicit: [true,true], value: 'implicit scalar with tag' } 16 - !Scalar { implicit: [false,false], tag: '!mytag', value: 'data' } 17 - !Scalar { implicit: [true,true], value: 'quoted scalar with tag' } 18 - !Scalar { value: 'data', style: '"', tag: '!mytag', implicit: [false,false] } 19 - !Scalar { implicit: [true,true], value: 'block scalar with tag' } 20 - !Scalar { value: 'data', style: '|', tag: '!mytag', implicit: [false,false] } 21 - !Scalar { implicit: [true,true], value: 'single character' } 22 - !Scalar { value: 'a', implicit: [true,true] } 23 - !Scalar { implicit: [true,true], value: 'single digit' } 24 - !Scalar { value: '1', implicit: [true,false] } 25 25 - !MappingEnd 26 26 - !DocumentEnd -
pyyaml/trunk/tests/data/sequences.events
r132 r137 7 7 8 8 - !DocumentStart 9 - !SequenceStart { tag: '!mytag' }9 - !SequenceStart { tag: '!mytag', implicit: false } 10 10 - !SequenceEnd 11 11 - !DocumentEnd … … 15 15 - !SequenceStart 16 16 - !SequenceEnd 17 - !SequenceStart { tag: '!mytag' }17 - !SequenceStart { tag: '!mytag', implicit: false } 18 18 - !SequenceEnd 19 19 - !SequenceStart 20 20 - !Scalar 21 21 - !Scalar { value: 'data' } 22 - !Scalar { tag: '!mytag', value: 'data' }22 - !Scalar { tag: '!mytag', implicit: [false,false], value: 'data' } 23 23 - !SequenceEnd 24 24 - !SequenceStart … … 30 30 - !SequenceEnd 31 31 - !SequenceStart 32 - !SequenceStart { tag: '!mytag' }32 - !SequenceStart { tag: '!mytag', implicit: false } 33 33 - !SequenceStart 34 34 - !Scalar { value: 'data' } … … 48 48 - !SequenceEnd 49 49 - !Scalar { value: 'key2' } 50 - !SequenceStart { tag: '!mytag1' }50 - !SequenceStart { tag: '!mytag1', implicit: false } 51 51 - !Scalar { value: 'data3' } 52 52 - !SequenceStart … … 54 54 - !Scalar { value: 'data5' } 55 55 - !SequenceEnd 56 - !SequenceStart { tag: '!mytag2' }56 - !SequenceStart { tag: '!mytag2', implicit: false } 57 57 - !Scalar { value: 'data6' } 58 58 - !Scalar { value: 'data7' } … … 70 70 - !Scalar 71 71 - !Scalar { value: 'data' } 72 - !Scalar { tag: '!mytag', value: 'data' }73 - !SequenceStart { tag: '!mytag' }72 - !Scalar { tag: '!mytag', implicit: [false,false], value: 'data' } 73 - !SequenceStart { tag: '!mytag', implicit: false } 74 74 - !Scalar { value: 'data' } 75 75 - !Scalar { value: 'data' } -
pyyaml/trunk/tests/data/sloppy-indentation.canonical
r117 r137 16 16 "the parser does not require scalars to be indented with at least one space" 17 17 --- !!map 18 { ? !!str "foo": { ? !!str "bar" : "quoted scalars may not adhere indentation" } }18 { ? !!str "foo": { ? !!str "bar" : !!str "quoted scalars may not adhere indentation" } } -
pyyaml/trunk/tests/test_appliance.py
r136 r137 263 263 tag = self.get_token_value() 264 264 if self.check_token(ScalarToken): 265 self.events.append(ScalarEvent(anchor, tag, False, self.get_token_value(), None, None))265 self.events.append(ScalarEvent(anchor, tag, (False, False), self.get_token_value(), None, None)) 266 266 elif self.check_token(FlowSequenceStartToken): 267 267 self.events.append(SequenceStartEvent(anchor, tag, None, None)) … … 322 322 return self.events[0] 323 323 324 class CanonicalLoader(CanonicalScanner, CanonicalParser, Composer, Constructor, Detector):324 class CanonicalLoader(CanonicalScanner, CanonicalParser, Composer, Constructor, Resolver): 325 325 326 326 def __init__(self, stream): … … 331 331 Composer.__init__(self) 332 332 Constructor.__init__(self) 333 Detector.__init__(self)333 Resolver.__init__(self) 334 334 335 335 def canonical_scan(stream): -
pyyaml/trunk/tests/test_emitter.py
r136 r137 31 31 if isinstance(event, ScalarEvent): 32 32 #self.failUnlessEqual(event.implicit, new_event.implicit) 33 if not event.implicit and notnew_event.implicit:33 if True not in event.implicit+new_event.implicit: 34 34 self.failUnlessEqual(event.tag, new_event.tag) 35 35 self.failUnlessEqual(event.value, new_event.value) … … 59 59 if class_name in ['ScalarEvent', 'SequenceStartEvent', 'MappingStartEvent']: 60 60 mapping.setdefault('tag', None) 61 if class_name in ['SequenceStartEvent', 'MappingStartEvent']: 62 mapping.setdefault('implicit', True) 61 63 if class_name == 'ScalarEvent': 62 mapping.setdefault('implicit', False)64 mapping.setdefault('implicit', (False, True)) 63 65 mapping.setdefault('value', '') 64 66 value = getattr(yaml, class_name)(**mapping) -
pyyaml/trunk/tests/test_resolver.py
r136 r137 4 4 from yaml import * 5 5 6 class TestDetector(test_appliance.TestAppliance): 6 class MyLoader(Loader): 7 pass 7 8 8 def _testDetector(self, test_name, data_filename, detect_filename): 9 class MyDumper(Dumper): 10 pass 11 12 add_path_resolver(u'!root', [], 13 Loader=MyLoader, Dumper=MyDumper) 14 15 add_path_resolver(u'!root/scalar', [], str, 16 Loader=MyLoader, Dumper=MyDumper) 17 18 add_path_resolver(u'!root/key11/key12/*', ['key11', 'key12'], 19 Loader=MyLoader, Dumper=MyDumper) 20 21 add_path_resolver(u'!root/key21/1/*', ['key21', 1], 22 Loader=MyLoader, Dumper=MyDumper) 23 24 add_path_resolver(u'!root/key31/*/*/key14/map', ['key31', None, None, 'key14'], map, 25 Loader=MyLoader, Dumper=MyDumper) 26 27 class TestResolver(test_appliance.TestAppliance): 28 29 def _testImplicitResolver(self, test_name, data_filename, detect_filename): 9 30 node = None 10 31 correct_tag = None … … 26 47 raise 27 48 28 TestDetector.add_tests('testDetector', '.data', '.detect') 49 def _testPathResolverLoader(self, test_name, data_filename, path_filename): 50 #print serialize_all(compose_all(file(data_filename, 'rb').read(), Loader=MyLoader)) 51 nodes1 = compose_all(file(data_filename, 'rb').read(), Loader=MyLoader) 52 nodes2 = compose_all(file(path_filename, 'rb').read()) 53 for node1, node2 in zip(nodes1, nodes2): 54 self.failUnlessEqual(self._convert(node1), self._convert(node2)) 29 55 56 def _testPathResolverDumper(self, test_name, data_filename, path_filename): 57 for filename in [data_filename, path_filename]: 58 output = serialize_all(compose_all(file(filename, 'rb').read()), Dumper=MyDumper) 59 #print output 60 nodes1 = compose_all(output) 61 nodes2 = compose_all(file(data_filename, 'rb').read()) 62 for node1, node2 in zip(nodes1, nodes2): 63 self.failUnlessEqual(self._convert(node1), self._convert(node2)) 64 65 def _convert(self, node): 66 if isinstance(node, ScalarNode): 67 return node.tag, node.value 68 elif isinstance(node, SequenceNode): 69 value = [] 70 for item in node.value: 71 value.append(self._convert(item)) 72 return node.tag, value 73 elif isinstance(node, MappingNode): 74 value = [] 75 for key in node.value: 76 item = node.value[key] 77 value.append((self._convert(key), self._convert(item))) 78 value.sort() 79 return node.tag, value 80 81 TestResolver.add_tests('testImplicitResolver', '.data', '.detect') 82 TestResolver.add_tests('testPathResolverLoader', '.data', '.path') 83 TestResolver.add_tests('testPathResolverDumper', '.data', '.path') 84 -
pyyaml/trunk/tests/test_yaml.py
r133 r137 8 8 from test_structure import * 9 9 from test_errors import * 10 from test_ detector import *10 from test_resolver import * 11 11 from test_constructor import * 12 12 from test_emitter import *
Note: See TracChangeset
for help on using the changeset viewer.
