~ubuntu-branches/ubuntu/lucid/python2.6/lucid

« back to all changes in this revision

Viewing changes to Lib/lib2to3/pgen2/tokenize.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2010-03-11 13:30:19 UTC
  • mto: (10.1.13 sid)
  • mto: This revision was merged to the branch mainline in revision 44.
  • Revision ID: james.westby@ubuntu.com-20100311133019-sblbooa3uqrkoe70
Tags: upstream-2.6.5~rc2
ImportĀ upstreamĀ versionĀ 2.6.5~rc2

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
    'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro'
31
31
 
32
32
import string, re
 
33
from codecs import BOM_UTF8, lookup
33
34
from lib2to3.pgen2.token import *
34
35
 
35
36
from . import token
143
144
 
144
145
class StopTokenizing(Exception): pass
145
146
 
146
 
def printtoken(type, token, (srow, scol), (erow, ecol), line): # for testing
 
147
def printtoken(type, token, start, end, line): # for testing
 
148
    (srow, scol) = start
 
149
    (erow, ecol) = end
147
150
    print "%d,%d-%d,%d:\t%s\t%s" % \
148
151
        (srow, scol, erow, ecol, tok_name[type], repr(token))
149
152
 
226
229
                startline = False
227
230
            toks_append(tokval)
228
231
 
 
232
cookie_re = re.compile("coding[:=]\s*([-\w.]+)")
 
233
 
 
234
def _get_normal_name(orig_enc):
 
235
    """Imitates get_normal_name in tokenizer.c."""
 
236
    # Only care about the first 12 characters.
 
237
    enc = orig_enc[:12].lower().replace("_", "-")
 
238
    if enc == "utf-8" or enc.startswith("utf-8-"):
 
239
        return "utf-8"
 
240
    if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
 
241
       enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
 
242
        return "iso-8859-1"
 
243
    return orig_enc
 
244
 
 
245
def detect_encoding(readline):
 
246
    """
 
247
    The detect_encoding() function is used to detect the encoding that should
 
248
    be used to decode a Python source file. It requires one argment, readline,
 
249
    in the same way as the tokenize() generator.
 
250
 
 
251
    It will call readline a maximum of twice, and return the encoding used
 
252
    (as a string) and a list of any lines (left as bytes) it has read
 
253
    in.
 
254
 
 
255
    It detects the encoding from the presence of a utf-8 bom or an encoding
 
256
    cookie as specified in pep-0263. If both a bom and a cookie are present,
 
257
    but disagree, a SyntaxError will be raised. If the encoding cookie is an
 
258
    invalid charset, raise a SyntaxError.
 
259
 
 
260
    If no encoding is specified, then the default of 'utf-8' will be returned.
 
261
    """
 
262
    bom_found = False
 
263
    encoding = None
 
264
    def read_or_stop():
 
265
        try:
 
266
            return readline()
 
267
        except StopIteration:
 
268
            return b''
 
269
 
 
270
    def find_cookie(line):
 
271
        try:
 
272
            line_string = line.decode('ascii')
 
273
        except UnicodeDecodeError:
 
274
            return None
 
275
 
 
276
        matches = cookie_re.findall(line_string)
 
277
        if not matches:
 
278
            return None
 
279
        encoding = _get_normal_name(matches[0])
 
280
        try:
 
281
            codec = lookup(encoding)
 
282
        except LookupError:
 
283
            # This behaviour mimics the Python interpreter
 
284
            raise SyntaxError("unknown encoding: " + encoding)
 
285
 
 
286
        if bom_found:
 
287
            if codec.name != 'utf-8':
 
288
                # This behaviour mimics the Python interpreter
 
289
                raise SyntaxError('encoding problem: utf-8')
 
290
            else:
 
291
                # Allow it to be properly encoded and decoded.
 
292
                encoding = 'utf-8-sig'
 
293
        return encoding
 
294
 
 
295
    first = read_or_stop()
 
296
    if first.startswith(BOM_UTF8):
 
297
        bom_found = True
 
298
        first = first[3:]
 
299
    if not first:
 
300
        return 'utf-8', []
 
301
 
 
302
    encoding = find_cookie(first)
 
303
    if encoding:
 
304
        return encoding, [first]
 
305
 
 
306
    second = read_or_stop()
 
307
    if not second:
 
308
        return 'utf-8', [first]
 
309
 
 
310
    encoding = find_cookie(second)
 
311
    if encoding:
 
312
        return encoding, [first, second]
 
313
 
 
314
    return 'utf-8', [first, second]
 
315
 
229
316
def untokenize(iterable):
230
317
    """Transform tokens back into Python source code.
231
318
 
303
390
            column = 0
304
391
            while pos < max:                   # measure leading whitespace
305
392
                if line[pos] == ' ': column = column + 1
306
 
                elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize
 
393
                elif line[pos] == '\t': column = (column//tabsize + 1)*tabsize
307
394
                elif line[pos] == '\f': column = 0
308
395
                else: break
309
396
                pos = pos + 1