Changeset 139


Ignore:
Timestamp:
04/18/06 10:35:28 (8 years ago)
Author:
xi
Message:

Add constructors for some simple python types.

Location:
pyyaml/trunk/lib/yaml
Files:
3 edited

Legend:

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

    r136 r139  
    1818    from sets import Set as set 
    1919 
    20 import binascii, re 
     20import binascii, re, sys 
    2121 
    2222class ConstructorError(MarkedYAMLError): 
     
    6262                    constructor = lambda node:  \ 
    6363                            self.yaml_multi_constructors[tag_prefix](self, tag_suffix, node) 
    64                 break 
     64                    break 
    6565            else: 
    6666                if None in self.yaml_multi_constructors: 
     
    7676                elif isinstance(node, MappingNode): 
    7777                    constructor = self.construct_mapping 
     78                else: 
     79                    print node.tag 
    7880        data = constructor(node) 
    7981        self.constructed_objects[node] = data 
     
    350352 
    351353    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] 
     354        state = self.construct_mapping(node) 
    356355        data = cls.__new__(cls) 
    357356        if hasattr(data, '__setstate__'): 
    358             data.__setstate__(mapping) 
     357            data.__setstate__(state) 
    359358        else: 
    360             data.__dict__.update(mapping) 
     359            data.__dict__.update(state) 
    361360        return data 
    362361 
     
    419418 
    420419class Constructor(SafeConstructor): 
    421     pass 
    422  
     420 
     421    def construct_python_str(self, node): 
     422        return self.construct_scalar(node).encode('utf-8') 
     423 
     424    def construct_python_unicode(self, node): 
     425        return self.construct_scalar(node) 
     426 
     427    def construct_python_long(self, node): 
     428        return long(self.construct_yaml_int(node)) 
     429 
     430    def construct_python_complex(self, node): 
     431       return complex(self.construct_scalar(node)) 
     432 
     433    def construct_python_tuple(self, node): 
     434        return tuple(self.construct_yaml_seq(node)) 
     435 
     436    def find_python_module(self, name, mark): 
     437        if not name: 
     438            raise ConstructorError("while constructing a Python module", mark, 
     439                    "expected non-empty name appended to the tag", mark) 
     440        try: 
     441            __import__(name) 
     442        except ImportError, exc: 
     443            raise ConstructorError("while constructing a Python module", mark, 
     444                    "cannot find module %r (%s)" % (name.encode('utf-8'), exc), mark) 
     445        return sys.modules[name] 
     446 
     447    def find_python_name(self, name, mark): 
     448        if not name: 
     449            raise ConstructorError("while constructing a Python object", mark, 
     450                    "expected non-empty name appended to the tag", mark) 
     451        if u'.' in name: 
     452            module_name, object_name = name.rsplit('.', 1) 
     453        else: 
     454            module_name = '__builtin__' 
     455            object_name = name 
     456        try: 
     457            __import__(module_name) 
     458        except ImportError, exc: 
     459            raise ConstructorError("while constructing a Python object", mark, 
     460                    "cannot find module %r (%s)" % (module_name.encode('utf-8'), exc), mark) 
     461        module = sys.modules[module_name] 
     462        if not hasattr(module, object_name): 
     463            raise ConstructorError("while constructing a Python object", mark, 
     464                    "cannot find %r in the module %r" % (object_name.encode('utf-8'), 
     465                        module.__name__), mark) 
     466        return getattr(module, object_name) 
     467 
     468    def construct_python_name(self, suffix, node): 
     469        value = self.construct_scalar(node) 
     470        if value: 
     471            raise ConstructorError("while constructing a Python name", node.start_mark, 
     472                    "expected the empty value, but found %r" % value.encode('utf-8'), 
     473                    node.start_mark) 
     474        return self.find_python_name(suffix, node.start_mark) 
     475 
     476    def construct_python_module(self, suffix, node): 
     477        value = self.construct_scalar(node) 
     478        if value: 
     479            raise ConstructorError("while constructing a Python module", node.start_mark, 
     480                    "expected the empty value, but found %r" % value.encode('utf-8'), 
     481                    node.start_mark) 
     482        return self.find_python_module(suffix, node.start_mark) 
     483 
     484Constructor.add_constructor( 
     485    u'tag:yaml.org,2002:python/none', 
     486    Constructor.construct_yaml_null) 
     487 
     488Constructor.add_constructor( 
     489    u'tag:yaml.org,2002:python/bool', 
     490    Constructor.construct_yaml_bool) 
     491 
     492Constructor.add_constructor( 
     493    u'tag:yaml.org,2002:python/str', 
     494    Constructor.construct_python_str) 
     495 
     496Constructor.add_constructor( 
     497    u'tag:yaml.org,2002:python/unicode', 
     498    Constructor.construct_python_unicode) 
     499 
     500Constructor.add_constructor( 
     501    u'tag:yaml.org,2002:python/int', 
     502    Constructor.construct_yaml_int) 
     503 
     504Constructor.add_constructor( 
     505    u'tag:yaml.org,2002:python/long', 
     506    Constructor.construct_python_long) 
     507 
     508Constructor.add_constructor( 
     509    u'tag:yaml.org,2002:python/float', 
     510    Constructor.construct_yaml_float) 
     511 
     512Constructor.add_constructor( 
     513    u'tag:yaml.org,2002:python/complex', 
     514    Constructor.construct_python_complex) 
     515 
     516Constructor.add_constructor( 
     517    u'tag:yaml.org,2002:python/list', 
     518    Constructor.construct_yaml_seq) 
     519 
     520Constructor.add_constructor( 
     521    u'tag:yaml.org,2002:python/tuple', 
     522    Constructor.construct_python_tuple) 
     523 
     524Constructor.add_constructor( 
     525    u'tag:yaml.org,2002:python/dict', 
     526    Constructor.construct_yaml_map) 
     527 
     528Constructor.add_multi_constructor( 
     529    u'tag:yaml.org,2002:python/name:', 
     530    Constructor.construct_python_name) 
     531 
     532Constructor.add_multi_constructor( 
     533    u'tag:yaml.org,2002:python/module:', 
     534    Constructor.construct_python_module) 
     535 
  • pyyaml/trunk/lib/yaml/representer.py

    r137 r139  
    1717    from sets import Set as set 
    1818 
     19import sys 
     20 
    1921class RepresenterError(YAMLError): 
    2022    pass 
     
    3133        self.serialize(node) 
    3234        self.represented_objects = {} 
     35 
     36    class C: pass 
     37    c = C() 
     38    def f(): pass 
     39    classobj_type = type(C) 
     40    instance_type = type(c) 
     41    function_type = type(f) 
     42    builtin_function_type = type(abs) 
     43    module_type = type(sys) 
     44    del C, c, f 
     45 
     46    def get_classobj_bases(self, cls): 
     47        bases = [cls] 
     48        for base in cls.__bases__: 
     49            bases.extend(self.get_classobj_bases(base)) 
     50        return bases 
    3351 
    3452    def represent_object(self, data): 
     
    4462                return node 
    4563            self.represented_objects[alias_key] = None 
    46         for data_type in type(data).__mro__: 
     64        data_types = type(data).__mro__ 
     65        if type(data) is self.instance_type: 
     66            data_types = self.get_classobj_bases(data.__class__)+data_types 
     67        for data_type in data_types: 
    4768            if data_type in self.yaml_representers: 
    4869                node = self.yaml_representers[data_type](self, data) 
     
    7394 
    7495    def represent_mapping(self, tag, mapping, flow_style=None): 
    75         value = {} 
    7696        if hasattr(mapping, 'keys'): 
     97            value = {} 
    7798            for item_key in mapping.keys(): 
    7899                item_value = mapping[item_key] 
     
    80101                        self.represent_object(item_value) 
    81102        else: 
     103            value = [] 
    82104            for item_key, item_value in mapping: 
    83                 value[self.represent_object(item_key)] =    \ 
    84                         self.represent_object(item_value) 
     105                value.append((self.represent_object(item_key), 
     106                        self.represent_object(item_value))) 
    85107        return MappingNode(tag, value, flow_style=flow_style) 
    86108 
     
    101123 
    102124    def represent_str(self, data): 
    103         encoding = None 
     125        tag = None 
     126        style = None 
    104127        try: 
    105             unicode(data, 'ascii') 
    106             encoding = 'ascii' 
     128            data = unicode(data, 'ascii') 
     129            tag = u'tag:yaml.org,2002:str' 
    107130        except UnicodeDecodeError: 
    108131            try: 
    109                 unicode(data, 'utf-8') 
    110                 encoding = 'utf-8' 
     132                data = unicode(data, 'utf-8') 
     133                tag = u'tag:yaml.org,2002:str' 
    111134            except UnicodeDecodeError: 
    112                 pass 
    113         if encoding: 
    114             return self.represent_scalar(u'tag:yaml.org,2002:str', 
    115                     unicode(data, encoding)) 
    116         else: 
    117             return self.represent_scalar(u'tag:yaml.org,2002:binary', 
    118                     unicode(data.encode('base64')), style='|') 
     135                data = data.encode('base64') 
     136                tag = u'tag:yaml.org,2002:binary' 
     137                style = '|' 
     138        return self.represent_scalar(tag, data, style=style) 
    119139 
    120140    def represent_unicode(self, data): 
     
    145165            value = u'.nan' 
    146166        else: 
    147             value = unicode(data) 
     167            value = unicode(repr(data)) 
    148168        return self.represent_scalar(u'tag:yaml.org,2002:float', value) 
    149169 
    150170    def represent_list(self, data): 
    151         pairs = (len(data) > 0) 
    152         for item in data: 
    153             if not isinstance(item, tuple) or len(item) != 2: 
    154                 pairs = False 
    155                 break 
     171        pairs = (len(data) > 0 and isinstance(data, list)) 
     172        if pairs: 
     173            for item in data: 
     174                if not isinstance(item, tuple) or len(item) != 2: 
     175                    pairs = False 
     176                    break 
    156177        if not pairs: 
    157178            return self.represent_sequence(u'tag:yaml.org,2002:seq', data) 
     
    190211        else: 
    191212            state = data.__dict__.copy() 
    192         mapping = state 
    193         if hasattr(state, 'keys'): 
    194             mapping = [] 
    195             keys = state.keys() 
    196             keys.sort() 
    197             for key in keys: 
    198                 mapping.append((key.replace('_', '-'), state[key])) 
    199         return self.represent_mapping(tag, mapping, flow_style=flow_style) 
     213        return self.represent_mapping(tag, state, flow_style=flow_style) 
    200214 
    201215    def represent_undefined(self, data): 
     
    224238 
    225239SafeRepresenter.add_representer(list, 
     240        SafeRepresenter.represent_list) 
     241 
     242SafeRepresenter.add_representer(tuple, 
    226243        SafeRepresenter.represent_list) 
    227244 
     
    242259 
    243260class Representer(SafeRepresenter): 
    244     pass 
    245  
     261     
     262    def represent_str(self, data): 
     263        tag = None 
     264        style = None 
     265        try: 
     266            data = unicode(data, 'ascii') 
     267            tag = u'tag:yaml.org,2002:str' 
     268        except UnicodeDecodeError: 
     269            try: 
     270                data = unicode(data, 'utf-8') 
     271                tag = u'tag:yaml.org,2002:python/str' 
     272            except UnicodeDecodeError: 
     273                data = data.encode('base64') 
     274                tag = u'tag:yaml.org,2002:binary' 
     275                style = '|' 
     276        return self.represent_scalar(tag, data, style=style) 
     277 
     278    def represent_unicode(self, data): 
     279        tag = None 
     280        try: 
     281            data.encode('ascii') 
     282            tag = u'tag:yaml.org,2002:python/unicode' 
     283        except UnicodeEncodeError: 
     284            tag = u'tag:yaml.org,2002:str' 
     285        return self.represent_scalar(tag, data) 
     286 
     287    def represent_long(self, data): 
     288        tag = u'tag:yaml.org,2002:int' 
     289        if int(data) is not data: 
     290            tag = u'tag:yaml.org,2002:python/long' 
     291        return self.represent_scalar(tag, unicode(data)) 
     292 
     293    def represent_complex(self, data): 
     294        if data.real != 0.0: 
     295            data = u'%r+%rj' % (data.real, data.imag) 
     296        else: 
     297            data = u'%rj' % data.imag 
     298        return self.represent_scalar(u'tag:yaml.org,2002:python/complex', data) 
     299 
     300    def represent_tuple(self, data): 
     301        return self.represent_sequence(u'tag:yaml.org,2002:python/tuple', data) 
     302 
     303    def represent_name(self, data): 
     304        name = u'%s.%s' % (data.__module__, data.__name__) 
     305        return self.represent_scalar(u'tag:yaml.org,2002:python/name:'+name, u'') 
     306 
     307    def represent_module(self, data): 
     308        return self.represent_scalar( 
     309                u'tag:yaml.org,2002:python/module:'+data.__name__, u'') 
     310 
     311Representer.add_representer(str, 
     312        Representer.represent_str) 
     313 
     314Representer.add_representer(unicode, 
     315        Representer.represent_unicode) 
     316 
     317Representer.add_representer(long, 
     318        Representer.represent_long) 
     319 
     320Representer.add_representer(complex, 
     321        Representer.represent_complex) 
     322 
     323Representer.add_representer(tuple, 
     324        Representer.represent_tuple) 
     325 
     326Representer.add_representer(type, 
     327        Representer.represent_name) 
     328 
     329Representer.add_representer(Representer.classobj_type, 
     330        Representer.represent_name) 
     331 
     332Representer.add_representer(Representer.function_type, 
     333        Representer.represent_name) 
     334 
     335Representer.add_representer(Representer.builtin_function_type, 
     336        Representer.represent_name) 
     337 
     338Representer.add_representer(Representer.module_type, 
     339        Representer.represent_module) 
     340 
  • pyyaml/trunk/lib/yaml/serializer.py

    r137 r139  
    6868                    self.anchor_node(item) 
    6969            elif isinstance(node, MappingNode): 
    70                 for key in node.value: 
    71                     self.anchor_node(key) 
    72                     self.anchor_node(node.value[key]) 
     70                if hasattr(node.value, 'keys'): 
     71                    for key in node.value.keys(): 
     72                        self.anchor_node(key) 
     73                        self.anchor_node(node.value[key]) 
     74                else: 
     75                    for key, value in node.value: 
     76                        self.anchor_node(key) 
     77                        self.anchor_node(value) 
    7378 
    7479    def generate_anchor(self, node): 
Note: See TracChangeset for help on using the changeset viewer.