Ignore:
Timestamp:
08/03/06 12:07:29 (8 years ago)
Author:
xi
Message:

Subclass all base classes from object.

Hold references to the objects being represented (should fix #22).

The value of a mapping node is represented as a list of pairs (key, value)
now.

Sort dictionary items (fix #23).

Recursive structures are now loaded and dumped correctly, including complex
structures like recursive tuples (fix #5). Thanks Peter Murphy for the patches.
To make it possible, representer functions are allowed to be generators.
In this case, the first generated value is an object. Other values produced
by the representer are ignored.

Make Representer not try to guess !!pairs when a list is represented.
You need to construct a !!pairs node explicitly now.

Do not check for duplicate mapping keys as it didn't work correctly anyway.

File:
1 edited

Legend:

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

    r206 r222  
    2222    pass 
    2323 
    24 class BaseRepresenter: 
     24class BaseRepresenter(object): 
    2525 
    2626    yaml_representers = {} 
     
    3131        self.default_flow_style = default_flow_style 
    3232        self.represented_objects = {} 
     33        self.object_keeper = [] 
     34        self.alias_key = None 
    3335 
    3436    def represent(self, data): 
     
    3638        self.serialize(node) 
    3739        self.represented_objects = {} 
     40        self.object_keeper = [] 
     41        self.alias_key = None 
    3842 
    3943    class C: pass 
    4044    c = C() 
    4145    def f(): pass 
     46    def g(): yield None 
    4247    classobj_type = type(C) 
    4348    instance_type = type(c) 
    4449    function_type = type(f) 
     50    generator_type = type(g()) 
    4551    builtin_function_type = type(abs) 
    4652    module_type = type(sys) 
    47     del C, c, f 
     53    del C, c, f, g 
    4854 
    4955    def get_classobj_bases(self, cls): 
     
    5561    def represent_data(self, data): 
    5662        if self.ignore_aliases(data): 
    57             alias_key = None 
    58         else: 
    59             alias_key = id(data) 
    60         if alias_key is not None: 
    61             if alias_key in self.represented_objects: 
    62                 node = self.represented_objects[alias_key] 
    63                 if node is None: 
    64                     raise RepresenterError("recursive objects are not allowed: %r" % data) 
     63            self.alias_key = None 
     64        else: 
     65            self.alias_key = id(data) 
     66        if self.alias_key is not None: 
     67            if self.alias_key in self.represented_objects: 
     68                node = self.represented_objects[self.alias_key] 
     69                #if node is None: 
     70                #    raise RepresenterError("recursive objects are not allowed: %r" % data) 
    6571                return node 
    66             self.represented_objects[alias_key] = None 
     72            #self.represented_objects[alias_key] = None 
     73            self.object_keeper.append(data) 
    6774        data_types = type(data).__mro__ 
    6875        if type(data) is self.instance_type: 
     
    8289                else: 
    8390                    node = ScalarNode(None, unicode(data)) 
    84         if alias_key is not None: 
    85             self.represented_objects[alias_key] = node 
     91        #if alias_key is not None: 
     92        #    self.represented_objects[alias_key] = node 
    8693        return node 
    8794 
     
    101108        if style is None: 
    102109            style = self.default_style 
    103         return ScalarNode(tag, value, style=style) 
     110        node = ScalarNode(tag, value, style=style) 
     111        if self.alias_key is not None: 
     112            self.represented_objects[self.alias_key] = node 
     113        return node 
    104114 
    105115    def represent_sequence(self, tag, sequence, flow_style=None): 
     116        value = [] 
     117        node = SequenceNode(tag, value, flow_style=flow_style) 
     118        if self.alias_key is not None: 
     119            self.represented_objects[self.alias_key] = node 
    106120        best_style = True 
    107         value = [] 
    108121        for item in sequence: 
    109122            node_item = self.represent_data(item) 
    110123            if not (isinstance(node_item, ScalarNode) and not node_item.style): 
    111124                best_style = False 
    112             value.append(self.represent_data(item)) 
     125            value.append(node_item) 
    113126        if flow_style is None: 
    114             flow_style = self.default_flow_style 
     127            if self.default_flow_style is not None: 
     128                node.flow_style = self.default_flow_style 
     129            else: 
     130                node.flow_style = best_style 
     131        return node 
     132 
     133    def represent_mapping(self, tag, mapping, flow_style=None): 
     134        value = [] 
     135        node = MappingNode(tag, value, flow_style=flow_style) 
     136        if self.alias_key is not None: 
     137            self.represented_objects[self.alias_key] = node 
     138        best_style = True 
     139        if hasattr(mapping, 'items'): 
     140            mapping = mapping.items() 
     141            mapping.sort() 
     142        for item_key, item_value in mapping: 
     143            node_key = self.represent_data(item_key) 
     144            node_value = self.represent_data(item_value) 
     145            if not (isinstance(node_key, ScalarNode) and not node_key.style): 
     146                best_style = False 
     147            if not (isinstance(node_value, ScalarNode) and not node_value.style): 
     148                best_style = False 
     149            value.append((node_key, node_value)) 
    115150        if flow_style is None: 
    116             flow_style = best_style 
    117         return SequenceNode(tag, value, flow_style=flow_style) 
    118  
    119     def represent_mapping(self, tag, mapping, flow_style=None): 
    120         best_style = True 
    121         if hasattr(mapping, 'keys'): 
    122             value = {} 
    123             for item_key in mapping.keys(): 
    124                 item_value = mapping[item_key] 
    125                 node_key = self.represent_data(item_key) 
    126                 node_value = self.represent_data(item_value) 
    127                 if not (isinstance(node_key, ScalarNode) and not node_key.style): 
    128                     best_style = False 
    129                 if not (isinstance(node_value, ScalarNode) and not node_value.style): 
    130                     best_style = False 
    131                 value[node_key] = node_value 
    132         else: 
    133             value = [] 
    134             for item_key, item_value in mapping: 
    135                 node_key = self.represent_data(item_key) 
    136                 node_value = self.represent_data(item_value) 
    137                 if not (isinstance(node_key, ScalarNode) and not node_key.style): 
    138                     best_style = False 
    139                 if not (isinstance(node_value, ScalarNode) and not node_value.style): 
    140                     best_style = False 
    141                 value.append((node_key, node_value)) 
    142         if flow_style is None: 
    143             flow_style = self.default_flow_style 
    144         if flow_style is None: 
    145             flow_style = best_style 
    146         return MappingNode(tag, value, flow_style=flow_style) 
     151            if self.default_flow_style is not None: 
     152                node.flow_style = self.default_flow_style 
     153            else: 
     154                node.flow_style = best_style 
     155        return node 
    147156 
    148157    def ignore_aliases(self, data): 
     
    209218 
    210219    def represent_list(self, data): 
    211         pairs = (len(data) > 0 and isinstance(data, list)) 
    212         if pairs: 
    213             for item in data: 
    214                 if not isinstance(item, tuple) or len(item) != 2: 
    215                     pairs = False 
    216                     break 
    217         if not pairs: 
     220        #pairs = (len(data) > 0 and isinstance(data, list)) 
     221        #if pairs: 
     222        #    for item in data: 
     223        #        if not isinstance(item, tuple) or len(item) != 2: 
     224        #            pairs = False 
     225        #            break 
     226        #if not pairs: 
    218227            return self.represent_sequence(u'tag:yaml.org,2002:seq', data) 
    219         value = [] 
    220         for item_key, item_value in data: 
    221             value.append(self.represent_mapping(u'tag:yaml.org,2002:map', 
    222                 [(item_key, item_value)])) 
    223         return SequenceNode(u'tag:yaml.org,2002:pairs', value) 
     228        #value = [] 
     229        #for item_key, item_value in data: 
     230        #    value.append(self.represent_mapping(u'tag:yaml.org,2002:map', 
     231        #        [(item_key, item_value)])) 
     232        #return SequenceNode(u'tag:yaml.org,2002:pairs', value) 
    224233 
    225234    def represent_dict(self, data): 
     
    251260        else: 
    252261            state = data.__dict__.copy() 
    253         if isinstance(state, dict): 
    254             state = state.items() 
    255             state.sort() 
    256262        return self.represent_mapping(tag, state, flow_style=flow_style) 
    257263 
     
    385391            state = data.__dict__ 
    386392        if args is None and isinstance(state, dict): 
    387             state = state.items() 
    388             state.sort() 
    389393            return self.represent_mapping( 
    390394                    u'tag:yaml.org,2002:python/object:'+class_name, state) 
     
    445449        if not args and not listitems and not dictitems \ 
    446450                and isinstance(state, dict) and newobj: 
    447             state = state.items() 
    448             state.sort() 
    449451            return self.represent_mapping( 
    450452                    u'tag:yaml.org,2002:python/object:'+function_name, state) 
Note: See TracChangeset for help on using the changeset viewer.