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/emitter.py

    r133 r136  
    1212from events import * 
    1313 
     14import re 
     15 
    1416class EmitterError(YAMLError): 
    1517    pass 
     
    1820    def __init__(self, scalar, empty, multiline, 
    1921            allow_flow_plain, allow_block_plain, 
    20             allow_single_quoted, allow_double_quoted, allow_block): 
     22            allow_single_quoted, allow_double_quoted, 
     23            allow_block): 
    2124        self.scalar = scalar 
    2225        self.empty = empty 
     
    3538    } 
    3639 
    37     def __init__(self, writer): 
    38  
    39         # The writer should have the methods `write` and possibly `flush`. 
    40         self.writer = writer 
    41  
    42         # Encoding is provided by STREAM-START. 
     40    def __init__(self, stream, canonical=None, indent=None, width=None, 
     41            allow_unicode=None, line_break=None): 
     42 
     43        # The stream should have the methods `write` and possibly `flush`. 
     44        self.stream = stream 
     45 
     46        # Encoding can be overriden by STREAM-START. 
    4347        self.encoding = None 
    4448 
     
    7680 
    7781        # Formatting details. 
    78         self.canonical = False 
    79         self.allow_unicode = False 
     82        self.canonical = canonical 
     83        self.allow_unicode = allow_unicode 
     84        self.best_indent = 2 
     85        if indent and 1 < indent < 10: 
     86            self.best_indent = indent 
     87        self.best_width = 80 
     88        if width and width > self.best_indent*2: 
     89            self.best_width = width 
    8090        self.best_line_break = u'\n' 
    81         self.best_indent = 2 
    82         self.best_width = 80 
     91        if line_break in [u'\r', u'\n', u'\r\n']: 
     92            self.best_line_break = line_break 
     93 
     94        # Tag prefixes. 
    8395        self.tag_prefixes = None 
    8496 
    85         # Analyses cache. 
    86         self.anchor_text = None 
    87         self.tag_text = None 
    88         self.scalar_analysis = None 
    89         self.scalar_style = None 
     97        # Prepared anchor and tag. 
     98        self.prepared_anchor = None 
     99        self.prepared_tag = None 
     100 
     101        # Scalar analysis and style. 
     102        self.analysis = None 
     103        self.style = None 
    90104 
    91105    def emit(self, event): 
     
    140154    def expect_stream_start(self): 
    141155        if isinstance(self.event, StreamStartEvent): 
    142             self.encoding = self.event.encoding 
    143             self.canonical = self.event.canonical 
    144             self.allow_unicode = self.event.allow_unicode 
    145             if self.event.indent and self.event.indent > 1: 
    146                 self.best_indent = self.event.indent 
    147             if self.event.width and self.event.width > self.best_indent: 
    148                 self.best_width = self.event.width 
    149             if self.event.line_break in [u'\r', u'\n', u'\r\n']: 
    150                 self.best_line_break = self.event.line_break 
     156            if self.event.encoding: 
     157                self.encoding = self.event.encoding 
    151158            self.write_stream_start() 
    152159            self.state = self.expect_first_document_start 
     
    166173        if isinstance(self.event, DocumentStartEvent): 
    167174            if self.event.version: 
    168                 version_text = self.analyze_version(self.event.version) 
     175                version_text = self.prepare_version(self.event.version) 
    169176                self.write_version_directive(version_text) 
    170177            self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy() 
     
    175182                    prefix = self.event.tags[handle] 
    176183                    self.tag_prefixes[prefix] = handle 
    177                     handle_text = self.analyze_tag_handle(handle) 
    178                     prefix_text = self.analyze_tag_prefix(prefix) 
     184                    handle_text = self.prepare_tag_handle(handle) 
     185                    prefix_text = self.prepare_tag_prefix(prefix) 
    179186                    self.write_tag_directive(handle_text, prefix_text) 
    180187            implicit = (first and not self.event.explicit and not self.canonical 
     
    200207                self.write_indicator(u'...', True) 
    201208                self.write_indent() 
     209            self.flush_stream() 
    202210            self.state = self.expect_document_start 
    203211        else: 
     
    419427        length = 0 
    420428        if isinstance(self.event, NodeEvent) and self.event.anchor is not None: 
    421             if self.anchor_text is None: 
    422                 self.anchor_text = self.analyze_anchor(self.event.anchor) 
    423             length += len(self.anchor_text) 
     429            if self.prepared_anchor is None: 
     430                self.prepared_anchor = self.prepare_anchor(self.event.anchor) 
     431            length += len(self.prepared_anchor) 
    424432        if isinstance(self.event, (ScalarEvent, CollectionStartEvent))  \ 
    425433                and self.event.tag is not None: 
    426             if self.tag_text is None: 
    427                 self.tag_text = self.analyze_tag(self.event.tag) 
    428             length += len(self.tag_text) 
     434            if self.prepared_tag is None: 
     435                self.prepared_tag = self.prepare_tag(self.event.tag) 
     436            length += len(self.prepared_tag) 
    429437        if isinstance(self.event, ScalarEvent): 
    430             if self.scalar_analysis is None: 
    431                 self.scalar_analysis = self.analyze_scalar(self.event.value) 
    432             length += len(self.scalar_analysis.scalar) 
     438            if self.analysis is None: 
     439                self.analysis = self.analyze_scalar(self.event.value) 
     440            length += len(self.analysis.scalar) 
    433441        return (length < 128 and (isinstance(self.event, AliasEvent) 
    434             or (isinstance(self.event, ScalarEvent) and not self.scalar_analysis.multiline) 
     442            or (isinstance(self.event, ScalarEvent) 
     443                    and not self.analysis.empty and not self.analysis.multiline) 
    435444            or self.check_empty_sequence() or self.check_empty_mapping())) 
    436445 
     
    439448    def process_anchor(self, indicator): 
    440449        if self.event.anchor is None: 
     450            self.prepared_anchor = None 
    441451            return 
    442         if self.anchor_text is None: 
    443             self.anchor_text = self.analyze_anchor(self.event.anchor) 
    444         if self.anchor_text: 
    445             self.write_indicator(indicator+self.anchor_text, True) 
    446         self.anchor_text = None 
     452        if self.prepared_anchor is None: 
     453            self.prepared_anchor = self.prepare_anchor(self.event.anchor) 
     454        if self.prepared_anchor: 
     455            self.write_indicator(indicator+self.prepared_anchor, True) 
     456        self.prepared_anchor = None 
    447457 
    448458    def process_tag(self): 
    449         if self.event.tag is None: 
     459        tag = self.event.tag 
     460        if isinstance(self.event, ScalarEvent): 
     461            if self.style is None: 
     462                self.style = self.choose_scalar_style() 
     463            if self.style == '': 
     464                self.prepared_tag = None 
     465                return 
     466            if self.event.implicit and not tag: 
     467                tag = u'!' 
     468                self.prepared_tag = None 
     469        if not tag: 
     470            self.prepared_tag = None 
    450471            return 
    451         if isinstance(self.event, ScalarEvent) and self.best_scalar_style() == '': 
    452             return 
    453         if self.tag_text is None: 
    454             self.tag_text = self.analyze_tag(self.event.tag) 
    455         if self.tag_text: 
    456             self.write_indicator(self.tag_text, True) 
    457         self.tag_text = None 
    458  
    459     def best_scalar_style(self): 
    460         if self.scalar_analysis is None: 
    461             self.scalar_analysis = self.analyze_scalar(self.event.value) 
    462         if self.canonical: 
     472        if self.prepared_tag is None: 
     473            self.prepared_tag = self.prepare_tag(tag) 
     474        if self.prepared_tag: 
     475            self.write_indicator(self.prepared_tag, True) 
     476        self.prepared_tag = None 
     477 
     478    def choose_scalar_style(self): 
     479        if self.analysis is None: 
     480            self.analysis = self.analyze_scalar(self.event.value) 
     481        if self.event.style == '"' or self.canonical: 
    463482            return '"' 
    464         if (self.event.implicit and not self.event.style 
    465                 and ((self.flow_level and self.scalar_analysis.allow_flow_plain) 
    466                     or (not self.flow_level and self.scalar_analysis.allow_block_plain)) 
    467                 and (len(self.scalar_analysis.scalar) > 0 
    468                     or (not self.flow_level and not self.simple_key_context))): 
    469             return '' 
    470         elif self.event.style == '\'' and self.scalar_analysis.allow_single_quoted: 
    471             return '\'' 
    472         elif self.event.style in ['|', '>'] and not self.flow_level and self.scalar_analysis.allow_block: 
    473             return self.event.style 
    474         else: 
    475             return '"' 
    476         return style 
     483        if not self.event.style and self.event.implicit: 
     484            if (not (self.simple_key_context and 
     485                    (self.analysis.empty or self.analysis.multiline)) 
     486                and (self.flow_level and self.analysis.allow_flow_plain 
     487                    or (not self.flow_level and self.analysis.allow_block_plain))): 
     488                return '' 
     489        if self.event.style and self.event.style in '|>': 
     490            if not self.flow_level and self.analysis.allow_block: 
     491                return self.event.style 
     492        if not self.event.style or self.event.style == '\'': 
     493            if (self.analysis.allow_single_quoted and 
     494                    not (self.simple_key_context and self.analysis.multiline)): 
     495                return '\'' 
     496        return '"' 
    477497 
    478498    def process_scalar(self): 
    479         if self.scalar_analysis is None: 
    480             self.scalar_analysis = self.analyze_scalar(self.event.value) 
    481         style = self.best_scalar_style() 
    482         if self.scalar_analysis.multiline and not self.simple_key_context   \ 
    483                 and style not in ['|', '>']: 
    484             self.write_indent() 
    485         if style == '"': 
    486             self.write_double_quoted(self.scalar_analysis.scalar, 
    487                     split=(not self.simple_key_context)) 
    488         elif style == '\'': 
    489             self.write_single_quoted(self.scalar_analysis.scalar, 
    490                     split=(not self.simple_key_context)) 
    491         elif style == '>': 
    492             self.write_folded(self.scalar_analysis.scalar) 
    493         elif style == '|': 
    494             self.write_literal(self.scalar_analysis.scalar) 
    495         else: 
    496             self.write_plain(self.scalar_analysis.scalar, 
    497                     split=(not self.simple_key_context)) 
    498         self.scalar_analysis = None 
     499        if self.analysis is None: 
     500            self.analysis = self.analyze_scalar(self.event.value) 
     501        if self.style is None: 
     502            self.style = self.choose_scalar_style() 
     503        split = (not self.simple_key_context) 
     504        #if self.analysis.multiline and split    \ 
     505        #        and (not self.style or self.style in '\'\"'): 
     506        #    self.write_indent() 
     507        if self.style == '"': 
     508            self.write_double_quoted(self.analysis.scalar, split) 
     509        elif self.style == '\'': 
     510            self.write_single_quoted(self.analysis.scalar, split) 
     511        elif self.style == '>': 
     512            self.write_folded(self.analysis.scalar) 
     513        elif self.style == '|': 
     514            self.write_literal(self.analysis.scalar) 
     515        else: 
     516            self.write_plain(self.analysis.scalar, split) 
     517        self.analysis = None 
     518        self.style = None 
    499519 
    500520    # Analyzers. 
    501521 
    502     def analyze_version(self, version): 
     522    def prepare_version(self, version): 
    503523        major, minor = version 
    504524        if major != 1: 
     
    506526        return u'%d.%d' % (major, minor) 
    507527 
    508     def analyze_tag_handle(self, handle): 
     528    def prepare_tag_handle(self, handle): 
    509529        if not handle: 
    510530            raise EmitterError("tag handle must not be empty") 
     
    519539        return handle 
    520540 
    521     def analyze_tag_prefix(self, prefix): 
     541    def prepare_tag_prefix(self, prefix): 
    522542        if not prefix: 
    523543            raise EmitterError("tag prefix must not be empty") 
     
    542562        return u''.join(chunks) 
    543563 
    544     def analyze_tag(self, tag): 
     564    def prepare_tag(self, tag): 
    545565        if not tag: 
    546566            raise EmitterError("tag must not be empty") 
     567        if tag == u'!': 
     568            return tag 
    547569        handle = None 
    548570        suffix = tag 
     
    575597            return u'!<%s>' % suffix_text 
    576598 
    577     def analyze_anchor(self, anchor): 
     599    def prepare_anchor(self, anchor): 
    578600        if not anchor: 
    579601            raise EmitterError("anchor must not be empty") 
     
    585607        return anchor 
    586608 
    587     def analyze_scalar(self, scalar):   # It begs for refactoring. 
     609    def analyze_scalar(self, scalar): 
     610 
     611        # Empty scalar is a special case. 
    588612        if not scalar: 
    589613            return ScalarAnalysis(scalar=scalar, empty=True, multiline=False, 
     
    591615                    allow_single_quoted=True, allow_double_quoted=True, 
    592616                    allow_block=False) 
    593         contains_block_indicator = False 
    594         contains_flow_indicator = False 
    595         contains_line_breaks = False 
    596         contains_unicode_characters = False 
    597         contains_special_characters = False 
    598         contains_inline_spaces = False          # non-space space+ non-space 
    599         contains_inline_breaks = False          # non-space break+ non-space 
    600         contains_leading_spaces = False         # ^ space+ (non-space | $) 
    601         contains_leading_breaks = False         # ^ break+ (non-space | $) 
    602         contains_trailing_spaces = False        # non-space space+ $ 
    603         contains_trailing_breaks = False        # non-space break+ $ 
    604         contains_inline_breaks_spaces = False   # non-space break+ space+ non-space 
    605         contains_mixed_breaks_spaces = False    # anything else 
     617 
     618        # Indicators and special characters. 
     619        block_indicators = False 
     620        flow_indicators = False 
     621        line_breaks = False 
     622        special_characters = False 
     623 
     624        # Whitespaces. 
     625        inline_spaces = False          # non-space space+ non-space 
     626        inline_breaks = False          # non-space break+ non-space 
     627        leading_spaces = False         # ^ space+ (non-space | $) 
     628        leading_breaks = False         # ^ break+ (non-space | $) 
     629        trailing_spaces = False        # (^ | non-space) space+ $ 
     630        trailing_breaks = False        # (^ | non-space) break+ $ 
     631        inline_breaks_spaces = False   # non-space break+ space+ non-space 
     632        mixed_breaks_spaces = False    # anything else 
     633 
     634        # Check document indicators. 
    606635        if scalar.startswith(u'---') or scalar.startswith(u'...'): 
    607             contains_block_indicator = True 
    608             contains_flow_indicator = True 
    609         first = True 
    610         last = (len(scalar) == 1) 
    611         preceeded_by_space = False 
    612         followed_by_space = (len(scalar) > 1 and 
     636            block_indicators = True 
     637            flow_indicators = True 
     638 
     639        # First character or preceded by a whitespace. 
     640        preceeded_by_space = True 
     641 
     642        # Last character or followed by a whitespace. 
     643        followed_by_space = (len(scalar) == 1 or 
    613644                scalar[1] in u'\0 \t\r\n\x85\u2028\u2029') 
    614         spaces = breaks = mixed = leading = False 
     645 
     646        # The current series of whitespaces contain plain spaces. 
     647        spaces = False 
     648 
     649        # The current series of whitespaces contain line breaks. 
     650        breaks = False 
     651 
     652        # The current series of whitespaces contain a space followed by a 
     653        # break. 
     654        mixed = False 
     655 
     656        # The current series of whitespaces start at the beginning of the 
     657        # scalar. 
     658        leading = False 
     659 
    615660        index = 0 
    616661        while index < len(scalar): 
    617662            ch = scalar[index] 
    618             if first: 
     663 
     664            # Check for indicators. 
     665 
     666            if index == 0: 
     667                # Leading indicators are special characters. 
    619668                if ch in u'#,[]{}#&*!|>\'\"%@`':  
    620                     contains_flow_indicator = True 
    621                     contains_block_indicator = True 
     669                    flow_indicators = True 
     670                    block_indicators = True 
    622671                if ch in u'?:': 
    623                     contains_flow_indicator = True 
    624                     if followed_by_space or last: 
    625                         contains_block_indicator = True 
    626                 if ch == u'-' and (followed_by_space or last): 
    627                     contains_flow_indicator = True 
    628                     contains_block_indicator = True 
     672                    flow_indicators = True 
     673                    if followed_by_space: 
     674                        block_indicators = True 
     675                if ch == u'-' and followed_by_space: 
     676                    flow_indicators = True 
     677                    block_indicators = True 
    629678            else: 
     679                # Some indicators cannot appear within a scalar as well. 
    630680                if ch in u',?[]{}': 
    631                     contains_flow_indicator = True 
     681                    flow_indicators = True 
    632682                if ch == u':': 
    633                     contains_flow_indicator = True 
    634                     if followed_by_space or last: 
    635                         contains_block_indicator = True 
    636                 if ch == u'#' and (preceeded_by_space or first): 
    637                     contains_flow_indicator = True 
    638                     contains_block_indicator = True 
     683                    flow_indicators = True 
     684                    if followed_by_space: 
     685                        block_indicators = True 
     686                if ch == u'#' and preceeded_by_space: 
     687                    flow_indicators = True 
     688                    block_indicators = True 
     689 
     690            # Check for line breaks, special, and unicode characters. 
     691 
    639692            if ch in u'\n\x85\u2028\u2029': 
    640                 contains_line_breaks = True 
     693                line_breaks = True 
    641694            if not (ch == u'\n' or u'\x20' <= ch <= u'\x7E'): 
    642                 if ch < u'\x80': 
    643                     contains_special_characters = True 
     695                if ch < u'\x80' or ch == u'\uFEFF': # '\uFEFF' is BOM. 
     696                    special_characters = True 
    644697                else: 
    645                     contains_unicode_characters = True 
    646             if ch == u' ': 
    647                 if not spaces and not breaks: 
    648                     leading = first 
    649                 spaces = True 
    650             elif ch in u'\n\x85\u2028\u2029': 
    651                 if not spaces and not breaks: 
    652                     leading = first 
    653                 breaks = True 
    654                 if spaces: 
    655                     mixed = True 
    656             if ch not in u' \n\x85\u2028\u2029': 
     698                    unicode_characters = True 
     699                    if not self.allow_unicode: 
     700                        special_characters = True 
     701 
     702            # Spaces, line breaks, and how they are mixed. State machine. 
     703 
     704            # Start or continue series of whitespaces. 
     705            if ch in u' \n\x85\u2028\u2029': 
     706                if spaces and breaks: 
     707                    if ch != u' ':      # break+ (space+ break+)    => mixed 
     708                        mixed = True 
     709                elif spaces: 
     710                    if ch != u' ':      # (space+ break+)   => mixed 
     711                        breaks = True 
     712                        mixed = True 
     713                elif breaks: 
     714                    if ch == u' ':      # break+ space+ 
     715                        spaces = True 
     716                else: 
     717                    leading = (index == 0) 
     718                    if ch == u' ':      # space+ 
     719                        spaces = True 
     720                    else:               # break+ 
     721                        breaks = True 
     722 
     723            # Series of whitespaces ended with a non-space. 
     724            elif spaces or breaks: 
    657725                if leading: 
    658726                    if spaces and breaks: 
    659                         contains_mixed_breaks_spaces = True 
     727                        mixed_breaks_spaces = True 
    660728                    elif spaces: 
    661                         contains_leading_spaces = True 
     729                        leading_spaces = True 
    662730                    elif breaks: 
    663                         contains_leading_breaks = True 
     731                        leading_breaks = True 
    664732                else: 
    665733                    if mixed: 
    666                         contains_mixed_break_spaces = True 
     734                        mixed_breaks_spaces = True 
    667735                    elif spaces and breaks: 
    668                         contains_inline_breaks_spaces = True 
     736                        inline_breaks_spaces = True 
    669737                    elif spaces: 
    670                         contains_inline_spaces = True 
     738                        inline_spaces = True 
    671739                    elif breaks: 
    672                         contains_inline_breaks = True 
     740                        inline_breaks = True 
    673741                spaces = breaks = mixed = leading = False 
    674             elif last: 
     742 
     743            # Series of whitespaces reach the end. 
     744            if (spaces or breaks) and (index == len(scalar)-1): 
    675745                if spaces and breaks: 
    676                     contains_mixed_break_spaces = True 
     746                    mixed_breaks_spaces = True 
    677747                elif spaces: 
     748                    trailing_spaces = True 
    678749                    if leading: 
    679                         contains_leading_spaces = True 
    680                     else: 
    681                         contains_trailing_spaces = True 
     750                        leading_spaces = True 
    682751                elif breaks: 
     752                    trailing_breaks = True 
    683753                    if leading: 
    684                         contains_leading_breaks = True 
    685                     else: 
    686                         contains_trailing_breaks = True 
     754                        leading_breaks = True 
     755                spaces = breaks = mixed = leading = False 
     756 
     757            # Prepare for the next character. 
    687758            index += 1 
    688             first = False 
    689             last = (index+1 == len(scalar)) 
    690759            preceeded_by_space = (ch in u'\0 \t\r\n\x85\u2028\u2029') 
    691             followed_by_space = (index+1 < len(scalar) and 
     760            followed_by_space = (index+1 >= len(scalar) or 
    692761                    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 
    695         allow_flow_plain = not (contains_flow_indicator or contains_special_characters 
    696             or contains_leading_spaces or contains_leading_breaks 
    697             or contains_trailing_spaces or contains_trailing_breaks 
    698             or contains_inline_breaks_spaces or contains_mixed_breaks_spaces) 
    699         allow_block_plain = not (contains_block_indicator or contains_special_characters 
    700             or contains_leading_spaces or contains_leading_breaks 
    701             or contains_trailing_spaces or contains_trailing_breaks 
    702             or contains_inline_breaks_spaces or contains_mixed_breaks_spaces) 
    703         allow_single_quoted = not (contains_special_characters 
    704             or contains_inline_breaks_spaces or contains_mixed_breaks_spaces) 
     762 
     763        # Let's decide what styles are allowed. 
     764        allow_flow_plain = True 
     765        allow_block_plain = True 
     766        allow_single_quoted = True 
    705767        allow_double_quoted = True 
    706         allow_block = not (contains_special_characters 
    707             or contains_leading_spaces or contains_leading_breaks 
    708             or contains_trailing_spaces or contains_mixed_breaks_spaces) 
    709         return ScalarAnalysis(scalar=scalar, empty=False, multiline=contains_line_breaks, 
    710                 allow_flow_plain=allow_flow_plain, allow_block_plain=allow_block_plain, 
    711                 allow_single_quoted=allow_single_quoted, allow_double_quoted=allow_double_quoted, 
     768        allow_block = True 
     769 
     770        # Leading and trailing whitespace are bad for plain scalars. We also 
     771        # do not want to mess with leading whitespaces for block scalars. 
     772        if leading_spaces or leading_breaks or trailing_spaces: 
     773            allow_flow_plain = allow_block_plain = allow_block = False 
     774 
     775        # Trailing breaks are fine for block scalars, but unacceptable for 
     776        # plain scalars. 
     777        if trailing_breaks: 
     778            allow_flow_plain = allow_block_plain = False 
     779 
     780        # The combination of (space+ break+) is only acceptable for block 
     781        # scalars. 
     782        if inline_breaks_spaces: 
     783            allow_flow_plain = allow_block_plain = allow_single_quoted = False 
     784 
     785        # Mixed spaces and breaks, as well as special character are only 
     786        # allowed for double quoted scalars. 
     787        if mixed_breaks_spaces or special_characters: 
     788            allow_flow_plain = allow_block_plain =  \ 
     789            allow_single_quoted = allow_block = False 
     790 
     791        # We don't emit multiline plain scalars. 
     792        if line_breaks: 
     793            allow_flow_plain = allow_block_plain = False 
     794 
     795        # Flow indicators are forbidden for flow plain scalars. 
     796        if flow_indicators: 
     797            allow_flow_plain = False 
     798 
     799        # Block indicators are forbidden for block plain scalars. 
     800        if block_indicators: 
     801            allow_block_plain = False 
     802 
     803        return ScalarAnalysis(scalar=scalar, 
     804                empty=False, multiline=line_breaks, 
     805                allow_flow_plain=allow_flow_plain, 
     806                allow_block_plain=allow_block_plain, 
     807                allow_single_quoted=allow_single_quoted, 
     808                allow_double_quoted=allow_double_quoted, 
    712809                allow_block=allow_block) 
    713810 
    714811    # Writers. 
     812 
     813    def flush_stream(self): 
     814        if hasattr(self.stream, 'flush'): 
     815            self.stream.flush() 
    715816 
    716817    def write_stream_start(self): 
    717818        # Write BOM if needed. 
    718819        if self.encoding and self.encoding.startswith('utf-16'): 
    719             self.writer.write(u'\xFF\xFE'.encode(self.encoding)) 
     820            self.stream.write(u'\xFF\xFE'.encode(self.encoding)) 
    720821 
    721822    def write_stream_end(self): 
    722         if hasattr(self.writer, 'flush'): 
    723             self.writer.flush() 
     823        self.flush_stream() 
    724824 
    725825    def write_indicator(self, indicator, need_whitespace, 
     
    734834        if self.encoding: 
    735835            data = data.encode(self.encoding) 
    736         self.writer.write(data) 
     836        self.stream.write(data) 
    737837 
    738838    def write_indent(self): 
     
    747847            if self.encoding: 
    748848                data = data.encode(self.encoding) 
    749             self.writer.write(data) 
     849            self.stream.write(data) 
    750850 
    751851    def write_line_break(self, data=None): 
     
    758858        if self.encoding: 
    759859            data = data.encode(self.encoding) 
    760         self.writer.write(data) 
     860        self.stream.write(data) 
    761861 
    762862    def write_version_directive(self, version_text): 
     
    764864        if self.encoding: 
    765865            data = data.encode(self.encoding) 
    766         self.writer.write(data) 
     866        self.stream.write(data) 
    767867        self.write_line_break() 
    768868 
     
    771871        if self.encoding: 
    772872            data = data.encode(self.encoding) 
    773         self.writer.write(data) 
     873        self.stream.write(data) 
    774874        self.write_line_break() 
    775875 
    776     # Scalar writers. 
     876    # Scalar streams. 
    777877 
    778878    def write_single_quoted(self, text, split=True): 
     
    795895                        if self.encoding: 
    796896                            data = data.encode(self.encoding) 
    797                         self.writer.write(data) 
     897                        self.stream.write(data) 
    798898                    start = end 
    799899            elif breaks: 
     
    815915                        if self.encoding: 
    816916                            data = data.encode(self.encoding) 
    817                         self.writer.write(data) 
     917                        self.stream.write(data) 
    818918                        start = end 
    819919                    if ch == u'\'': 
     
    822922                        if self.encoding: 
    823923                            data = data.encode(self.encoding) 
    824                         self.writer.write(data) 
     924                        self.stream.write(data) 
    825925                        start = end + 1 
    826926            if ch is not None: 
     
    864964                    if self.encoding: 
    865965                        data = data.encode(self.encoding) 
    866                     self.writer.write(data) 
     966                    self.stream.write(data) 
    867967                    start = end 
    868968                if ch is not None: 
     
    878978                    if self.encoding: 
    879979                        data = data.encode(self.encoding) 
    880                     self.writer.write(data) 
     980                    self.stream.write(data) 
    881981                    start = end+1 
    882982            if 0 < end < len(text)-1 and (ch == u' ' or start >= end)   \ 
     
    888988                if self.encoding: 
    889989                    data = data.encode(self.encoding) 
    890                 self.writer.write(data) 
     990                self.stream.write(data) 
    891991                self.write_indent() 
    892992                self.whitespace = False 
     
    897997                    if self.encoding: 
    898998                        data = data.encode(self.encoding) 
    899                     self.writer.write(data) 
     999                    self.stream.write(data) 
    9001000            end += 1 
    9011001        self.write_indicator(u'"', False) 
     
    9481048                        if self.encoding: 
    9491049                            data = data.encode(self.encoding) 
    950                         self.writer.write(data) 
     1050                        self.stream.write(data) 
    9511051                    start = end 
    9521052            else: 
     
    9551055                    if self.encoding: 
    9561056                        data = data.encode(self.encoding) 
    957                     self.writer.write(data) 
     1057                    self.stream.write(data) 
    9581058                    if ch is None: 
    9591059                        self.write_line_break() 
     
    9891089                    if self.encoding: 
    9901090                        data = data.encode(self.encoding) 
    991                     self.writer.write(data) 
     1091                    self.stream.write(data) 
    9921092                    if ch is None: 
    9931093                        self.write_line_break() 
     
    10051105            if self.encoding: 
    10061106                data = data.encode(self.encoding) 
    1007             self.writer.write(data) 
     1107            self.stream.write(data) 
    10081108        self.writespace = False 
    10091109        self.indention = False 
     
    10261126                        if self.encoding: 
    10271127                            data = data.encode(self.encoding) 
    1028                         self.writer.write(data) 
     1128                        self.stream.write(data) 
    10291129                    start = end 
    10301130            elif breaks: 
     
    10471147                    if self.encoding: 
    10481148                        data = data.encode(self.encoding) 
    1049                     self.writer.write(data) 
     1149                    self.stream.write(data) 
    10501150                    start = end 
    10511151            if ch is not None: 
Note: See TracChangeset for help on using the changeset viewer.