Ignore:
Timestamp:
12/29/08 12:24:05 (6 years ago)
Author:
xi
Message:

Added basic support for Python 3 (Thanks idadesub(at)users(dot)sourceforge(dot)net).

Location:
pyyaml/trunk/lib3
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • pyyaml/trunk/lib3/yaml/reader.py

    r323 r328  
    1818__all__ = ['Reader', 'ReaderError'] 
    1919 
    20 from error import YAMLError, Mark 
     20from .error import YAMLError, Mark 
    2121 
    2222import codecs, re 
    23  
    24 # Unfortunately, codec functions in Python 2.3 does not support the `finish` 
    25 # arguments, so we have to write our own wrappers. 
    26  
    27 try: 
    28     codecs.utf_8_decode('', 'strict', False) 
    29     from codecs import utf_8_decode, utf_16_le_decode, utf_16_be_decode 
    30  
    31 except TypeError: 
    32  
    33     def utf_16_le_decode(data, errors, finish=False): 
    34         if not finish and len(data) % 2 == 1: 
    35             data = data[:-1] 
    36         return codecs.utf_16_le_decode(data, errors) 
    37  
    38     def utf_16_be_decode(data, errors, finish=False): 
    39         if not finish and len(data) % 2 == 1: 
    40             data = data[:-1] 
    41         return codecs.utf_16_be_decode(data, errors) 
    42  
    43     def utf_8_decode(data, errors, finish=False): 
    44         if not finish: 
    45             # We are trying to remove a possible incomplete multibyte character 
    46             # from the suffix of the data. 
    47             # The first byte of a multi-byte sequence is in the range 0xc0 to 0xfd. 
    48             # All further bytes are in the range 0x80 to 0xbf. 
    49             # UTF-8 encoded UCS characters may be up to six bytes long. 
    50             count = 0 
    51             while count < 5 and count < len(data)   \ 
    52                     and '\x80' <= data[-count-1] <= '\xBF': 
    53                 count -= 1 
    54             if count < 5 and count < len(data)  \ 
    55                     and '\xC0' <= data[-count-1] <= '\xFD': 
    56                 data = data[:-count-1] 
    57         return codecs.utf_8_decode(data, errors) 
    5823 
    5924class ReaderError(YAMLError): 
     
    6732 
    6833    def __str__(self): 
    69         if isinstance(self.character, str): 
     34        if isinstance(self.character, bytes): 
    7035            return "'%s' codec can't decode byte #x%02x: %s\n"  \ 
    7136                    "  in \"%s\", position %d"    \ 
     
    8045class Reader(object): 
    8146    # Reader: 
    82     # - determines the data encoding and converts it to unicode, 
     47    # - determines the data encoding and converts it to a unicode string, 
    8348    # - checks if characters are in allowed range, 
    8449    # - adds '\0' to the end. 
    8550 
    8651    # Reader accepts 
     52    #  - a `bytes` object, 
    8753    #  - a `str` object, 
    88     #  - a `unicode` object, 
    8954    #  - a file-like object with its `read` method returning `str`, 
    9055    #  - a file-like object with its `read` method returning `unicode`. 
     
    9762        self.stream_pointer = 0 
    9863        self.eof = True 
    99         self.buffer = u'' 
     64        self.buffer = '' 
    10065        self.pointer = 0 
    10166        self.raw_buffer = None 
     
    10570        self.line = 0 
    10671        self.column = 0 
    107         if isinstance(stream, unicode): 
     72        if isinstance(stream, str): 
    10873            self.name = "<unicode string>" 
    10974            self.check_printable(stream) 
    110             self.buffer = stream+u'\0' 
    111         elif isinstance(stream, str): 
    112             self.name = "<string>" 
     75            self.buffer = stream+'\0' 
     76        elif isinstance(stream, bytes): 
     77            self.name = "<byte string>" 
    11378            self.raw_buffer = stream 
    11479            self.determine_encoding() 
     
    11782            self.name = getattr(stream, 'name', "<file>") 
    11883            self.eof = False 
    119             self.raw_buffer = '' 
     84            self.raw_buffer = None 
    12085            self.determine_encoding() 
    12186 
     
    139104            self.pointer += 1 
    140105            self.index += 1 
    141             if ch in u'\n\x85\u2028\u2029'  \ 
    142                     or (ch == u'\r' and self.buffer[self.pointer] != u'\n'): 
     106            if ch in '\n\x85\u2028\u2029'  \ 
     107                    or (ch == '\r' and self.buffer[self.pointer] != '\n'): 
    143108                self.line += 1 
    144109                self.column = 0 
    145             elif ch != u'\uFEFF': 
     110            elif ch != '\uFEFF': 
    146111                self.column += 1 
    147112            length -= 1 
     
    156121 
    157122    def determine_encoding(self): 
    158         while not self.eof and len(self.raw_buffer) < 2: 
     123        while not self.eof and (self.raw_buffer is None or len(self.raw_buffer) < 2): 
    159124            self.update_raw() 
    160         if not isinstance(self.raw_buffer, unicode): 
     125        if isinstance(self.raw_buffer, bytes): 
    161126            if self.raw_buffer.startswith(codecs.BOM_UTF16_LE): 
    162                 self.raw_decode = utf_16_le_decode 
     127                self.raw_decode = codecs.utf_16_le_decode 
    163128                self.encoding = 'utf-16-le' 
    164129            elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE): 
    165                 self.raw_decode = utf_16_be_decode 
     130                self.raw_decode = codecs.utf_16_be_decode 
    166131                self.encoding = 'utf-16-be' 
    167132            else: 
    168                 self.raw_decode = utf_8_decode 
     133                self.raw_decode = codecs.utf_8_decode 
    169134                self.encoding = 'utf-8' 
    170135        self.update(1) 
    171136 
    172     NON_PRINTABLE = re.compile(u'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]') 
     137    NON_PRINTABLE = re.compile('[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]') 
    173138    def check_printable(self, data): 
    174139        match = self.NON_PRINTABLE.search(data) 
     
    191156                    data, converted = self.raw_decode(self.raw_buffer, 
    192157                            'strict', self.eof) 
    193                 except UnicodeDecodeError, exc: 
     158                except UnicodeDecodeError as exc: 
    194159                    character = exc.object[exc.start] 
    195160                    if self.stream is not None: 
     
    206171            self.raw_buffer = self.raw_buffer[converted:] 
    207172            if self.eof: 
    208                 self.buffer += u'\0' 
     173                self.buffer += '\0' 
    209174                self.raw_buffer = None 
    210175                break 
    211176 
    212     def update_raw(self, size=1024): 
     177    def update_raw(self, size=4096): 
    213178        data = self.stream.read(size) 
    214         if data: 
     179        if self.raw_buffer is None: 
     180            self.raw_buffer = data 
     181        else: 
    215182            self.raw_buffer += data 
    216             self.stream_pointer += len(data) 
    217         else: 
     183        self.stream_pointer += len(data) 
     184        if not data: 
    218185            self.eof = True 
    219186 
Note: See TracChangeset for help on using the changeset viewer.