Ignore:
Timestamp:
04/15/06 19:54:52 (9 years ago)
Author:
xi
Message:

Major refactoring.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pyyaml/trunk/lib/yaml/constructor.py

    r133 r136  
    55from error import * 
    66from nodes import * 
     7from composer import * 
    78 
    89try: 
     
    2223    pass 
    2324 
    24 class BaseConstructor: 
    25  
    26     def __init__(self, resolver): 
    27         self.resolver = resolver 
     25class BaseConstructor(Composer): 
     26 
     27    yaml_constructors = {} 
     28    yaml_multi_constructors = {} 
     29 
     30    def __init__(self): 
    2831        self.constructed_objects = {} 
    2932 
    30     def check(self): 
     33    def check_data(self): 
    3134        # If there are more documents available? 
    32         return self.resolver.check() 
    33  
    34     def get(self): 
     35        return self.check_node() 
     36 
     37    def get_data(self): 
    3538        # Construct and return the next document. 
    36         if self.resolver.check(): 
    37             return self.construct_document(self.resolver.get()) 
     39        if self.check_node(): 
     40            return self.construct_document(self.get_node()) 
    3841 
    3942    def __iter__(self): 
    4043        # Iterator protocol. 
    41         while self.resolver.check(): 
    42             yield self.construct_document(self.resolver.get()) 
     44        while self.check_node(): 
     45            yield self.construct_document(self.get_node()) 
    4346 
    4447    def construct_document(self, node): 
    45         native = self.construct_object(node) 
     48        data = self.construct_object(node) 
    4649        self.constructed_objects = {} 
    47         return native 
     50        return data 
    4851 
    4952    def construct_object(self, node): 
    5053        if node in self.constructed_objects: 
    5154            return self.constructed_objects[node] 
     55        constructor = None 
    5256        if node.tag in self.yaml_constructors: 
    53             native = self.yaml_constructors[node.tag](self, node) 
    54         elif None in self.yaml_constructors: 
    55             native = self.yaml_constructors[None](self, node) 
    56         elif isinstance(node, ScalarNode): 
    57             native = self.construct_scalar(node) 
    58         elif isinstance(node, SequenceNode): 
    59             native = self.construct_sequence(node) 
    60         elif isinstance(node, MappingNode): 
    61             native = self.construct_mapping(node) 
    62         self.constructed_objects[node] = native 
    63         return native 
     57            constructor = lambda node: self.yaml_constructors[node.tag](self, node) 
     58        else: 
     59            for tag_prefix in self.yaml_multi_constructors: 
     60                if node.tag.startswith(tag_prefix): 
     61                    tag_suffix = node.tag[len(tag_prefix):] 
     62                    constructor = lambda node:  \ 
     63                            self.yaml_multi_constructors[tag_prefix](self, tag_suffix, node) 
     64                break 
     65            else: 
     66                if None in self.yaml_multi_constructors: 
     67                    constructor = lambda node:  \ 
     68                            self.yaml_multi_constructors[None](self, node.tag, node) 
     69                elif None in self.yaml_constructors: 
     70                    constructor = lambda node:  \ 
     71                            self.yaml_constructors[None](self, node) 
     72                elif isinstance(node, ScalarNode): 
     73                    constructor = self.construct_scalar 
     74                elif isinstance(node, SequenceNode): 
     75                    constructor = self.construct_sequence 
     76                elif isinstance(node, MappingNode): 
     77                    constructor = self.construct_mapping 
     78        data = constructor(node) 
     79        self.constructed_objects[node] = data 
     80        return data 
    6481 
    6582    def construct_scalar(self, node): 
     
    153170    add_constructor = classmethod(add_constructor) 
    154171 
    155     yaml_constructors = {} 
     172    def add_multi_constructor(cls, tag_prefix, multi_constructor): 
     173        if not 'yaml_multi_constructors' in cls.__dict__: 
     174            cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy() 
     175        cls.yaml_multi_constructors[tag_prefix] = multi_constructor 
     176    add_multi_constructor = classmethod(add_multi_constructor) 
    156177 
    157178class SafeConstructor(BaseConstructor): 
     
    328349        return self.construct_mapping(node) 
    329350 
     351    def construct_yaml_object(self, node, cls): 
     352        mapping = self.construct_mapping(node) 
     353        state = {} 
     354        for key in mapping: 
     355            state[key.replace('-', '_')] = mapping[key] 
     356        data = cls.__new__(cls) 
     357        if hasattr(data, '__setstate__'): 
     358            data.__setstate__(mapping) 
     359        else: 
     360            data.__dict__.update(mapping) 
     361        return data 
     362 
    330363    def construct_undefined(self, node): 
    331364        raise ConstructorError(None, None, 
Note: See TracChangeset for help on using the changeset viewer.