| [53] | 1 | |
|---|
| [133] | 2 | __all__ = ['Resolver', 'ResolverError'] |
|---|
| [57] | 3 | |
|---|
| 4 | from error import MarkedYAMLError |
|---|
| [133] | 5 | from detector import Detector |
|---|
| [53] | 6 | from nodes import * |
|---|
| 7 | |
|---|
| [55] | 8 | import re |
|---|
| 9 | |
|---|
| [57] | 10 | # Not really used. |
|---|
| 11 | class ResolverError(MarkedYAMLError): |
|---|
| 12 | pass |
|---|
| 13 | |
|---|
| [133] | 14 | class Resolver(Detector): |
|---|
| [53] | 15 | |
|---|
| 16 | DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str' |
|---|
| 17 | DEFAULT_SEQUENCE_TAG = u'tag:yaml.org,2002:seq' |
|---|
| 18 | DEFAULT_MAPPING_TAG = u'tag:yaml.org,2002:map' |
|---|
| 19 | |
|---|
| 20 | def __init__(self, composer): |
|---|
| 21 | self.composer = composer |
|---|
| 22 | self.resolved_nodes = {} |
|---|
| 23 | |
|---|
| 24 | def check(self): |
|---|
| 25 | # If there are more documents available? |
|---|
| 26 | return self.composer.check() |
|---|
| 27 | |
|---|
| 28 | def get(self): |
|---|
| 29 | # Resolve and return the root node of the next document. |
|---|
| 30 | if self.composer.check(): |
|---|
| 31 | return self.resolve_document(self.composer.get()) |
|---|
| 32 | |
|---|
| 33 | def __iter__(self): |
|---|
| 34 | # Iterator protocol. |
|---|
| 35 | while self.composer.check(): |
|---|
| 36 | yield self.resolve_document(self.composer.get()) |
|---|
| 37 | |
|---|
| 38 | def resolve_document(self, node): |
|---|
| 39 | self.resolve_node([], node) |
|---|
| 40 | return node |
|---|
| 41 | self.resolved_nodes = {} |
|---|
| 42 | |
|---|
| 43 | def resolve_node(self, path, node): |
|---|
| 44 | if node in self.resolved_nodes: |
|---|
| 45 | return |
|---|
| 46 | self.resolved_nodes[node] = None |
|---|
| 47 | if isinstance(node, ScalarNode): |
|---|
| 48 | self.resolve_scalar(path, node) |
|---|
| 49 | elif isinstance(node, SequenceNode): |
|---|
| 50 | self.resolve_sequence(path, node) |
|---|
| [54] | 51 | for index in range(len(node.value)): |
|---|
| [55] | 52 | self.resolve_node(path+[(node, index)], node.value[index]) |
|---|
| [53] | 53 | elif isinstance(node, MappingNode): |
|---|
| 54 | self.resolve_mapping(path, node) |
|---|
| [55] | 55 | for key in node.value: |
|---|
| [53] | 56 | self.resolve_node(path+[node, None], key) |
|---|
| [55] | 57 | self.resolve_node(path+[node, key], node.value[key]) |
|---|
| [53] | 58 | |
|---|
| [54] | 59 | def resolve_scalar(self, path, node): |
|---|
| [132] | 60 | if node.tag is None and node.implicit: |
|---|
| [133] | 61 | node.tag = self.detect(node.value) |
|---|
| [53] | 62 | if node.tag is None or node.tag == u'!': |
|---|
| 63 | node.tag = self.DEFAULT_SCALAR_TAG |
|---|
| 64 | |
|---|
| [54] | 65 | def resolve_sequence(self, path, node): |
|---|
| [53] | 66 | if node.tag is None or node.tag == u'!': |
|---|
| 67 | node.tag = self.DEFAULT_SEQUENCE_TAG |
|---|
| 68 | |
|---|
| [54] | 69 | def resolve_mapping(self, path, node): |
|---|
| [53] | 70 | if node.tag is None or node.tag == u'!': |
|---|
| 71 | node.tag = self.DEFAULT_MAPPING_TAG |
|---|
| 72 | |
|---|