Ignore:
Timestamp:
02/24/06 15:46:28 (8 years ago)
Author:
xi
Message:

Constructor is done.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/pyyaml3000/lib/yaml/constructor.py

    r55 r56  
    1414    from sets import Set as set 
    1515 
    16 import binascii 
     16import binascii, re 
    1717 
    1818class ConstructorError(MarkedYAMLError): 
     
    8484                    node.start_marker) 
    8585        mapping = {} 
     86        merge = None 
    8687        for key_node in node.value: 
    87             key = self.construct_object(key_node) 
    88             try: 
    89                 duplicate_key = key in mapping 
    90             except TypeError, exc: 
    91                 raise ConstructorError("while constructing a mapping", node.start_marker, 
    92                         "found unacceptable key (%s)" % exc, key_node.start_marker) 
    93             if duplicate_key: 
    94                 raise ConstructorError("while constructing a mapping", node.start_marker, 
    95                         "found duplicate key", key_node.start_marker) 
    96             value = self.construct_object(node.value[key_node]) 
    97             mapping[key] = value 
     88            if key_node.tag == u'tag:yaml.org,2002:merge': 
     89                if merge is not None: 
     90                    raise ConstructorError("while constructing a mapping", node.start_marker, 
     91                            "found duplicate merge key", key_node.start_marker) 
     92                    value_node = node.value[key_node] 
     93                    if isinstance(value_node, MappingNode): 
     94                        merge = [self.construct_mapping(value_node)] 
     95                    elif isinstance(value_node, SequenceNode): 
     96                        merge = [] 
     97                        for subnode in value_node.value: 
     98                            if not isinstance(subnode, MappingNode): 
     99                                raise ConstructorError("while constructing a mapping", 
     100                                        node.start_marker, 
     101                                        "expected a mapping for merging, but found %s" 
     102                                        % subnode.id, subnode.start_marker) 
     103                            merge.append(self.construct_mapping(subnode)) 
     104                        merge.reverse() 
     105                    else: 
     106                        raise ConstructorError("while constructing a mapping", node.start_marker, 
     107                                "expected a mapping or list of mappings for merging, but found %s" 
     108                                % value_node.id, value_node.start_marker) 
     109            elif key_node.tag == u'tag:yaml.org,2002:value': 
     110                if '=' in mapping: 
     111                    raise ConstructorError("while construction a mapping", node.start_marker, 
     112                            "found duplicate value key", key_node.start_marker) 
     113                value = self.construct_object(node.value[key_node]) 
     114                mapping['='] = value 
     115            else: 
     116                key = self.construct_object(key_node) 
     117                try: 
     118                    duplicate_key = key in mapping 
     119                except TypeError, exc: 
     120                    raise ConstructorError("while constructing a mapping", node.start_marker, 
     121                            "found unacceptable key (%s)" % exc, key_node.start_marker) 
     122                if duplicate_key: 
     123                    raise ConstructorError("while constructing a mapping", node.start_marker, 
     124                            "found duplicate key", key_node.start_marker) 
     125                value = self.construct_object(node.value[key_node]) 
     126                mapping[key] = value 
     127        if merge is not None: 
     128            merge.append(mapping) 
     129            mapping = {} 
     130            for submapping in merge: 
     131                mapping.update(submapping) 
    98132        return mapping 
    99133 
     
    202236                    "failed to decode base64 data: %s" % exc, node.start_mark)  
    203237 
     238    timestamp_regexp = re.compile( 
     239            ur'''^(?P<year>[0-9][0-9][0-9][0-9]) 
     240                -(?P<month>[0-9][0-9]?) 
     241                -(?P<day>[0-9][0-9]?) 
     242                (?:[Tt]|[ \t]+) 
     243                (?P<hour>[0-9][0-9]?) 
     244                :(?P<minute>[0-9][0-9]) 
     245                :(?P<second>[0-9][0-9]) 
     246                (?:\.(?P<fraction>[0-9]*))? 
     247                (?:[ \t]*(?:Z|(?P<tz_hour>[-+][0-9][0-9]?) 
     248                (?::(?P<tz_minute>[0-9][0-9])?)))?$''', re.X), 
     249 
     250    def construct_yaml_timestamp(self, node): 
     251        value = self.construct_scalar(node) 
     252        match = self.timestamp_expr.match(node.value) 
     253        values = match.groupdict() 
     254        for key in values: 
     255            if values[key]: 
     256                values[key] = int(values[key]) 
     257            else: 
     258                values[key] = 0 
     259        fraction = values['fraction'] 
     260        if micro: 
     261            while 10*fraction < 1000000: 
     262                fraction *= 10 
     263            values['fraction'] = fraction 
     264        stamp = datetime.datetime(values['year'], values['month'], values['day'], 
     265                values['hour'], values['minute'], values['second'], values['fraction']) 
     266        diff = datetime.timedelta(hours=values['tz_hour'], minutes=values['tz_minute']) 
     267        return stamp-diff 
     268 
     269    def construct_yaml_omap(self, node): 
     270        # Note: we do not check for duplicate keys, because it's too 
     271        # CPU-expensive. 
     272        if not isinstance(node, SequenceNode): 
     273            raise ConstructorError("while constructing an ordered map", node.start_marker, 
     274                    "expected a sequence, but found %s" % node.id, node.start_marker) 
     275        omap = [] 
     276        for subnode in node.value: 
     277            if not isinstance(subnode, MappingNode): 
     278                raise ConstructorError("while constructing an ordered map", node.start_marker, 
     279                        "expected a mapping of length 1, but found %s" % subnode.id, 
     280                        subnode.start_marker) 
     281                if len(subnode.value) != 1: 
     282                    raise ConstructorError("while constructing an ordered map", node.start_marker, 
     283                            "expected a single mapping item, but found %d items" % len(subnode.value), 
     284                            subnode.start_marker) 
     285                key_node = subnode.value.keys()[0] 
     286                key = self.construct_object(key_node) 
     287                value = self.construct_object(subnode.value[key_node]) 
     288                omap.append((key, value)) 
     289 
     290    def construct_yaml_pairs(self, node): 
     291        # Note: the same code as `construct_yaml_omap`. 
     292        if not isinstance(node, SequenceNode): 
     293            raise ConstructorError("while constructing pairs", node.start_marker, 
     294                    "expected a sequence, but found %s" % node.id, node.start_marker) 
     295        omap = [] 
     296        for subnode in node.value: 
     297            if not isinstance(subnode, MappingNode): 
     298                raise ConstructorError("while constructing pairs", node.start_marker, 
     299                        "expected a mapping of length 1, but found %s" % subnode.id, 
     300                        subnode.start_marker) 
     301                if len(subnode.value) != 1: 
     302                    raise ConstructorError("while constructing pairs", node.start_marker, 
     303                            "expected a single mapping item, but found %d items" % len(subnode.value), 
     304                            subnode.start_marker) 
     305                key_node = subnode.value.keys()[0] 
     306                key = self.construct_object(key_node) 
     307                value = self.construct_object(subnode.value[key_node]) 
     308                omap.append((key, value)) 
     309 
     310    def construct_yaml_set(self, node): 
     311        value = self.construct_mapping(node) 
     312        return set(value) 
     313 
    204314    def construct_yaml_str(self, node): 
    205315        value = self.construct_scalar(node) 
     
    209319            return value 
    210320 
     321    def construct_yaml_seq(self, node): 
     322        return self.construct_sequence(node) 
     323 
     324    def construct_yaml_map(self, node): 
     325        return self.construct_mapping(node) 
     326 
    211327Constructor.add_constructor( 
    212328        u'tag:yaml.org,2002:null', 
     
    226342 
    227343Constructor.add_constructor( 
     344        u'tag:yaml.org,2002:timestamp', 
     345        Constructor.construct_yaml_timestamp) 
     346 
     347Constructor.add_constructor( 
     348        u'tag:yaml.org,2002:omap', 
     349        Constructor.construct_yaml_omap) 
     350 
     351Constructor.add_constructor( 
     352        u'tag:yaml.org,2002:pairs', 
     353        Constructor.construct_yaml_pairs) 
     354 
     355Constructor.add_constructor( 
     356        u'tag:yaml.org,2002:set', 
     357        Constructor.construct_yaml_set) 
     358 
     359Constructor.add_constructor( 
    228360        u'tag:yaml.org,2002:str', 
    229361        Constructor.construct_yaml_str) 
     362 
     363Constructor.add_constructor( 
     364        u'tag:yaml.org,2002:seq', 
     365        Constructor.construct_yaml_seq) 
     366 
     367Constructor.add_constructor( 
     368        u'tag:yaml.org,2002:map', 
     369        Constructor.construct_yaml_map) 
    230370 
    231371class YAMLObjectMetaclass(type): 
Note: See TracChangeset for help on using the changeset viewer.