Changeset 133


Ignore:
Timestamp:
04/10/06 20:34:16 (9 years ago)
Author:
xi
Message:

Implement yaml.dump().

Location:
pyyaml/trunk
Files:
5 added
10 edited

Legend:

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

    r132 r133  
    11 
    22from error import * 
     3 
    34from reader import * 
    45from scanner import * 
     
    78from resolver import * 
    89from constructor import * 
     10 
    911from emitter import * 
     12from serializer import * 
     13from representer import * 
     14 
     15from detector import * 
    1016 
    1117from tokens import * 
    1218from events import * 
    1319from nodes import * 
     20 
     21from yaml_object import * 
    1422 
    1523def parse(data, Reader=Reader, Scanner=Scanner, Parser=Parser): 
     
    1927    return parser 
    2028 
    21 def load(data, Reader=Reader, Scanner=Scanner, Parser=Parser, 
     29def load_all(data, Reader=Reader, Scanner=Scanner, Parser=Parser, 
    2230        Composer=Composer, Resolver=Resolver, Constructor=Constructor): 
    2331    reader = Reader(data) 
     
    2937    return constructor 
    3038 
    31 def load_document(*args, **kwds): 
    32     for document in load(*args, **kwds): 
     39def safe_load_all(data, Reader=Reader, Scanner=Scanner, Parser=Parser, 
     40        Composer=Composer, Resolver=Resolver, Constructor=SafeConstructor): 
     41    return load_all(data, Reader, Scanner, Parser, Composer, Resolver, 
     42            Constructor) 
     43 
     44def load(data, *args, **kwds): 
     45    for document in load_all(data, *args, **kwds): 
    3346        return document 
    3447 
     48def safe_load(data, *args, **kwds): 
     49    for document in safe_load_all(data, *args, **kwds): 
     50        return document 
     51 
     52def emit(events, writer=None, Emitter=Emitter): 
     53    if writer is None: 
     54        try: 
     55            from cStringIO import StringIO 
     56        except ImportError: 
     57            from StringIO import StringIO 
     58        writer = StringIO() 
     59        return_value = True 
     60    else: 
     61        return_value = False 
     62    emitter = Emitter(writer) 
     63    for event in events: 
     64        emitter.emit(event) 
     65    if return_value: 
     66        return writer.getvalue() 
     67 
     68def dump_all(natives, writer=None, Emitter=Emitter, 
     69        Serializer=Serializer, Representer=Representer, 
     70        encoding=None, line_break=None, canonical=None, 
     71        indent=None, width=None, allow_unicode=None): 
     72    if writer is None: 
     73        try: 
     74            from cStringIO import StringIO 
     75        except ImportError: 
     76            from StringIO import StringIO 
     77        writer = StringIO() 
     78        return_value = True 
     79    else: 
     80        return_value = False 
     81    emitter = Emitter(writer) 
     82    serializer = Serializer(emitter, encoding=encoding, line_break=line_break, 
     83            canonical=canonical, indent=indent, width=width, 
     84            allow_unicode=allow_unicode) 
     85    representer = Representer(serializer) 
     86    for native in natives: 
     87        representer.represent(native) 
     88    representer.close() 
     89    if return_value: 
     90        return writer.getvalue() 
     91 
     92def safe_dump_all(natives, writer=None, Emitter=Emitter, 
     93        Serializer=Serializer, Representer=SafeRepresenter, 
     94        encoding=None, line_break=None, canonical=None, 
     95        indent=None, width=None, allow_unicode=None): 
     96    return dump_all(natives, writer, Emitter, Serializer, Representer, 
     97            encoding, line_break, canonical, indent, width, allow_unicode) 
     98 
     99def dump(native, *args, **kwds): 
     100    return dump_all([native], *args, **kwds) 
     101 
     102def safe_dump(native, *args, **kwds): 
     103    return safe_dump_all([native], *args, **kwds) 
     104 
  • pyyaml/trunk/lib/yaml/composer.py

    r132 r133  
    8383        event = self.parser.get() 
    8484        return ScalarNode(event.tag, event.value, event.implicit, 
    85                 event.start_mark, event.end_mark) 
     85                event.start_mark, event.end_mark, style=event.style) 
    8686 
    8787    def compose_sequence_node(self): 
     
    9292        end_event = self.parser.get() 
    9393        return SequenceNode(start_event.tag, value, 
    94                 start_event.start_mark, end_event.end_mark) 
     94                start_event.start_mark, end_event.end_mark, 
     95                flow_style=start_event.flow_style) 
    9596 
    9697    def compose_mapping_node(self): 
     
    107108        end_event = self.parser.get() 
    108109        return MappingNode(start_event.tag, value, 
    109                 start_event.start_mark, end_event.end_mark) 
     110                start_event.start_mark, end_event.end_mark, 
     111                flow_style=start_event.flow_style) 
    110112 
  • pyyaml/trunk/lib/yaml/constructor.py

    r116 r133  
    11 
    2 __all__ = ['BaseConstructor', 'Constructor', 'ConstructorError', 
    3     'YAMLObject', 'YAMLObjectMetaclass'] 
     2__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor', 
     3    'ConstructorError'] 
    44 
    55from error import * 
     
    155155    yaml_constructors = {} 
    156156 
    157 class Constructor(BaseConstructor): 
     157class SafeConstructor(BaseConstructor): 
    158158 
    159159    def construct_yaml_null(self, node): 
     
    333333                node.start_mark) 
    334334 
    335 Constructor.add_constructor( 
     335SafeConstructor.add_constructor( 
    336336        u'tag:yaml.org,2002:null', 
    337         Constructor.construct_yaml_null) 
    338  
    339 Constructor.add_constructor( 
     337        SafeConstructor.construct_yaml_null) 
     338 
     339SafeConstructor.add_constructor( 
    340340        u'tag:yaml.org,2002:bool', 
    341         Constructor.construct_yaml_bool) 
    342  
    343 Constructor.add_constructor( 
     341        SafeConstructor.construct_yaml_bool) 
     342 
     343SafeConstructor.add_constructor( 
    344344        u'tag:yaml.org,2002:int', 
    345         Constructor.construct_yaml_int) 
    346  
    347 Constructor.add_constructor( 
     345        SafeConstructor.construct_yaml_int) 
     346 
     347SafeConstructor.add_constructor( 
    348348        u'tag:yaml.org,2002:float', 
    349         Constructor.construct_yaml_float) 
    350  
    351 Constructor.add_constructor( 
     349        SafeConstructor.construct_yaml_float) 
     350 
     351SafeConstructor.add_constructor( 
    352352        u'tag:yaml.org,2002:binary', 
    353         Constructor.construct_yaml_binary) 
     353        SafeConstructor.construct_yaml_binary) 
    354354 
    355355if datetime_available: 
    356     Constructor.add_constructor( 
     356    SafeConstructor.add_constructor( 
    357357            u'tag:yaml.org,2002:timestamp', 
    358             Constructor.construct_yaml_timestamp) 
    359  
    360 Constructor.add_constructor( 
     358            SafeConstructor.construct_yaml_timestamp) 
     359 
     360SafeConstructor.add_constructor( 
    361361        u'tag:yaml.org,2002:omap', 
    362         Constructor.construct_yaml_omap) 
    363  
    364 Constructor.add_constructor( 
     362        SafeConstructor.construct_yaml_omap) 
     363 
     364SafeConstructor.add_constructor( 
    365365        u'tag:yaml.org,2002:pairs', 
    366         Constructor.construct_yaml_pairs) 
    367  
    368 Constructor.add_constructor( 
     366        SafeConstructor.construct_yaml_pairs) 
     367 
     368SafeConstructor.add_constructor( 
    369369        u'tag:yaml.org,2002:set', 
    370         Constructor.construct_yaml_set) 
    371  
    372 Constructor.add_constructor( 
     370        SafeConstructor.construct_yaml_set) 
     371 
     372SafeConstructor.add_constructor( 
    373373        u'tag:yaml.org,2002:str', 
    374         Constructor.construct_yaml_str) 
    375  
    376 Constructor.add_constructor( 
     374        SafeConstructor.construct_yaml_str) 
     375 
     376SafeConstructor.add_constructor( 
    377377        u'tag:yaml.org,2002:seq', 
    378         Constructor.construct_yaml_seq) 
    379  
    380 Constructor.add_constructor( 
     378        SafeConstructor.construct_yaml_seq) 
     379 
     380SafeConstructor.add_constructor( 
    381381        u'tag:yaml.org,2002:map', 
    382         Constructor.construct_yaml_map) 
    383  
    384 Constructor.add_constructor(None, 
    385         Constructor.construct_undefined) 
    386  
    387 class YAMLObjectMetaclass(type): 
    388  
    389     def __init__(cls, name, bases, kwds): 
    390         super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds) 
    391         if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None: 
    392             cls.yaml_constructor.add_constructor(cls.yaml_tag, cls.from_yaml) 
    393  
    394 class YAMLObject(object): 
    395  
    396     __metaclass__ = YAMLObjectMetaclass 
    397  
    398     yaml_constructor = Constructor 
    399  
    400     yaml_tag = None 
    401  
    402     def from_yaml(cls, constructor, node): 
    403         raise ConstructorError(None, None, 
    404                 "found undefined constructor for the tag %r" 
    405                 % node.tag.encode('utf-8'), node.start_mark) 
    406     from_yaml = classmethod(from_yaml) 
    407  
    408     def to_yaml(self): 
    409         assert False    # needs dumper 
    410  
     382        SafeConstructor.construct_yaml_map) 
     383 
     384SafeConstructor.add_constructor(None, 
     385        SafeConstructor.construct_undefined) 
     386 
     387class Constructor(SafeConstructor): 
     388    pass 
     389 
  • pyyaml/trunk/lib/yaml/emitter.py

    r132 r133  
    7777        # Formatting details. 
    7878        self.canonical = False 
     79        self.allow_unicode = False 
    7980        self.best_line_break = u'\n' 
    8081        self.best_indent = 2 
     
    141142            self.encoding = self.event.encoding 
    142143            self.canonical = self.event.canonical 
     144            self.allow_unicode = self.event.allow_unicode 
    143145            if self.event.indent and self.event.indent > 1: 
    144146                self.best_indent = self.event.indent 
     
    622624                    if followed_by_space or last: 
    623625                        contains_block_indicator = True 
    624                 if ch == u'-' and followed_by_space or last: 
     626                if ch == u'-' and (followed_by_space or last): 
    625627                    contains_flow_indicator = True 
    626628                    contains_block_indicator = True 
     
    632634                    if followed_by_space or last: 
    633635                        contains_block_indicator = True 
    634                 if ch == u'#' and preceeded_by_space: 
     636                if ch == u'#' and (preceeded_by_space or first): 
    635637                    contains_flow_indicator = True 
    636638                    contains_block_indicator = True 
     
    641643                    contains_special_characters = True 
    642644                else: 
    643                     contains_special_characters = True 
    644                     # TODO: We need an option to allow unescaped unicode 
    645                     # characters. 
    646645                    contains_unicode_characters = True 
    647646            if ch == u' ': 
     
    692691            followed_by_space = (index+1 < len(scalar) and 
    693692                    scalar[index+1] in u'\0 \t\r\n\x85\u2028\u2029') 
     693        if contains_unicode_characters and not self.allow_unicode: 
     694            contains_special_characters = True 
    694695        allow_flow_plain = not (contains_flow_indicator or contains_special_characters 
    695696            or contains_leading_spaces or contains_leading_breaks 
     
    854855            if end < len(text): 
    855856                ch = text[end] 
    856             if ch is None or not (u'\x20' <= ch <= u'\x7E') or ch in u'"\\': 
     857            if ch is None or ch in u'"\\'   \ 
     858                    or not (u'\x20' <= ch <= u'\x7E' 
     859                            or (self.allow_unicode and ch > u'\x7F' 
     860                                and ch not in u'\x85\u2028\u2029')): 
    857861                if start < end: 
    858862                    data = text[start:end] 
  • pyyaml/trunk/lib/yaml/events.py

    r132 r133  
    3636    def __init__(self, start_mark=None, end_mark=None, 
    3737            encoding=None, line_break=None, canonical=None, 
    38             indent=None, width=None): 
     38            indent=None, width=None, allow_unicode=None): 
    3939        self.start_mark = start_mark 
    4040        self.end_mark = end_mark 
     
    4444        self.indent = indent 
    4545        self.width = width 
     46        self.allow_unicode = allow_unicode 
    4647 
    4748class StreamEndEvent(Event): 
  • pyyaml/trunk/lib/yaml/nodes.py

    r132 r133  
    2424class ScalarNode(Node): 
    2525    id = 'scalar' 
    26     def __init__(self, tag, value, implicit, start_mark, end_mark): 
     26    def __init__(self, tag, value, implicit, 
     27            start_mark=None, end_mark=None, style=None): 
    2728        self.tag = tag 
    2829        self.value = value 
     
    3031        self.start_mark = start_mark 
    3132        self.end_mark = end_mark 
     33        self.style = style 
    3234 
    3335class CollectionNode(Node): 
    34     pass 
     36    def __init__(self, tag, value, 
     37            start_mark=None, end_mark=None, flow_style=None): 
     38        self.tag = tag 
     39        self.value = value 
     40        self.start_mark = start_mark 
     41        self.end_mark = end_mark 
     42        self.flow_style = flow_style 
    3543 
    3644class SequenceNode(CollectionNode): 
  • pyyaml/trunk/lib/yaml/resolver.py

    r132 r133  
    11 
    2 __all__ = ['BaseResolver', 'Resolver', 'ResolverError'] 
     2__all__ = ['Resolver', 'ResolverError'] 
    33 
    44from error import MarkedYAMLError 
     5from detector import Detector 
    56from nodes import * 
    67 
     
    1112    pass 
    1213 
    13 class BaseResolver: 
     14class Resolver(Detector): 
    1415 
    1516    DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str' 
     
    5859    def resolve_scalar(self, path, node): 
    5960        if node.tag is None and node.implicit: 
    60             node.tag = self.detect_scalar(node.value) 
     61            node.tag = self.detect(node.value) 
    6162        if node.tag is None or node.tag == u'!': 
    6263            node.tag = self.DEFAULT_SCALAR_TAG 
     
    7071            node.tag = self.DEFAULT_MAPPING_TAG 
    7172 
    72     def detect_scalar(self, value): 
    73         if value == u'': 
    74             detectors = self.yaml_detectors.get(u'', []) 
    75         else: 
    76             detectors = self.yaml_detectors.get(value[0], []) 
    77         detectors += self.yaml_detectors.get(None, []) 
    78         for tag, regexp in detectors: 
    79             if regexp.match(value): 
    80                 return tag 
    81  
    82     def add_detector(cls, tag, regexp, first): 
    83         if not 'yaml_detectors' in cls.__dict__: 
    84             cls.yaml_detectors = cls.yaml_detectors.copy() 
    85         for ch in first: 
    86             cls.yaml_detectors.setdefault(ch, []).append((tag, regexp)) 
    87     add_detector = classmethod(add_detector) 
    88  
    89     yaml_detectors = {} 
    90  
    91 class Resolver(BaseResolver): 
    92     pass 
    93  
    94 Resolver.add_detector( 
    95         u'tag:yaml.org,2002:bool', 
    96         re.compile(ur'''^(?:yes|Yes|YES|n|N|no|No|NO 
    97                     |true|True|TRUE|false|False|FALSE 
    98                     |on|On|ON|off|Off|OFF)$''', re.X), 
    99         list(u'yYnNtTfFoO')) 
    100  
    101 Resolver.add_detector( 
    102         u'tag:yaml.org,2002:float', 
    103         re.compile(ur'''^(?:[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*(?:[eE][-+][0-9]+)? 
    104                     |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]* 
    105                     |[-+]?\.(?:inf|Inf|INF) 
    106                     |\.(?:nan|NaN|NAN))$''', re.X), 
    107         list(u'-+0123456789.')) 
    108  
    109 Resolver.add_detector( 
    110         u'tag:yaml.org,2002:int', 
    111         re.compile(ur'''^(?:[-+]?0b[0-1_]+ 
    112                     |[-+]?0[0-7_]+ 
    113                     |[-+]?(?:0|[1-9][0-9_]*) 
    114                     |[-+]?0x[0-9a-fA-F_]+ 
    115                     |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X), 
    116         list(u'-+0123456789')) 
    117  
    118 Resolver.add_detector( 
    119         u'tag:yaml.org,2002:merge', 
    120         re.compile(ur'^(?:<<)$'), 
    121         ['<']) 
    122  
    123 Resolver.add_detector( 
    124         u'tag:yaml.org,2002:null', 
    125         re.compile(ur'''^(?: ~ 
    126                     |null|Null|NULL 
    127                     | )$''', re.X), 
    128         [u'~', u'n', u'N', u'']) 
    129  
    130 Resolver.add_detector( 
    131         u'tag:yaml.org,2002:timestamp', 
    132         re.compile(ur'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] 
    133                     |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]? 
    134                      (?:[Tt]|[ \t]+)[0-9][0-9]? 
    135                      :[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)? 
    136                      (?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X), 
    137         list(u'0123456789')) 
    138  
    139 Resolver.add_detector( 
    140         u'tag:yaml.org,2002:value', 
    141         re.compile(ur'^(?:=)$'), 
    142         ['=']) 
    143  
    144 # The following detector is only for documentation purposes. It cannot work 
    145 # because plain scalars cannot start with '!', '&', or '*'. 
    146 Resolver.add_detector( 
    147         u'tag:yaml.org,2002:yaml', 
    148         re.compile(ur'^(?:!|&|\*)$'), 
    149         list(u'!&*')) 
    150  
  • pyyaml/trunk/tests/data/scalars.events

    r130 r133  
    1919- !Scalar { implicit: true, value: 'block scalar with tag' } 
    2020- !Scalar { value: 'data', style: '|', tag: '!mytag' } 
     21- !Scalar { implicit: true, value: 'single character' } 
     22- !Scalar { value: 'a', implicit: true } 
     23- !Scalar { implicit: true, value: 'single digit' } 
     24- !Scalar { value: '1', implicit: true } 
    2125- !MappingEnd 
    2226- !DocumentEnd 
  • pyyaml/trunk/tests/test_emitter.py

    r132 r133  
    7676 
    7777    def _testEmitterEvents(self, test_name, events_filename): 
    78         events = list(load_document(file(events_filename, 'rb'), Constructor=EventsConstructor)) 
     78        events = list(load(file(events_filename, 'rb'), Constructor=EventsConstructor)) 
    7979        #self._dump(events_filename, events) 
    8080        writer = StringIO.StringIO() 
  • pyyaml/trunk/tests/test_yaml.py

    r132 r133  
    1111from test_constructor import * 
    1212from test_emitter import * 
     13from test_representer import * 
    1314from test_syck import * 
    1415 
Note: See TracChangeset for help on using the changeset viewer.