The detect_encoding() function is used to detect the encoding that should be used to decode a Python source file. It requires one argument, readline, in the same way as the tokenize() generator. It will call readline a maximum of twice, and return the encoding used (as a
(readline)
| 297 | return orig_enc |
| 298 | |
| 299 | def detect_encoding(readline): |
| 300 | """ |
| 301 | The detect_encoding() function is used to detect the encoding that should |
| 302 | be used to decode a Python source file. It requires one argument, readline, |
| 303 | in the same way as the tokenize() generator. |
| 304 | |
| 305 | It will call readline a maximum of twice, and return the encoding used |
| 306 | (as a string) and a list of any lines (left as bytes) it has read in. |
| 307 | |
| 308 | It detects the encoding from the presence of a utf-8 bom or an encoding |
| 309 | cookie as specified in pep-0263. If both a bom and a cookie are present, |
| 310 | but disagree, a SyntaxError will be raised. If the encoding cookie is an |
| 311 | invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, |
| 312 | 'utf-8-sig' is returned. |
| 313 | |
| 314 | If no encoding is specified, then the default of 'utf-8' will be returned. |
| 315 | """ |
| 316 | try: |
| 317 | filename = readline.__self__.name |
| 318 | except AttributeError: |
| 319 | filename = None |
| 320 | bom_found = False |
| 321 | encoding = None |
| 322 | default = 'utf-8' |
| 323 | def read_or_stop(): |
| 324 | try: |
| 325 | return readline() |
| 326 | except StopIteration: |
| 327 | return b'' |
| 328 | |
| 329 | def find_cookie(line): |
| 330 | try: |
| 331 | # Decode as UTF-8. Either the line is an encoding declaration, |
| 332 | # in which case it should be pure ASCII, or it must be UTF-8 |
| 333 | # per default encoding. |
| 334 | line_string = line.decode('utf-8') |
| 335 | except UnicodeDecodeError: |
| 336 | msg = "invalid or missing encoding declaration" |
| 337 | if filename is not None: |
| 338 | msg = '{} for {!r}'.format(msg, filename) |
| 339 | raise SyntaxError(msg) |
| 340 | |
| 341 | match = cookie_re.match(line_string) |
| 342 | if not match: |
| 343 | return None |
| 344 | encoding = _get_normal_name(match.group(1)) |
| 345 | try: |
| 346 | codec = lookup(encoding) |
| 347 | except LookupError: |
| 348 | # This behaviour mimics the Python interpreter |
| 349 | if filename is None: |
| 350 | msg = "unknown encoding: " + encoding |
| 351 | else: |
| 352 | msg = "unknown encoding for {!r}: {}".format(filename, |
| 353 | encoding) |
| 354 | raise SyntaxError(msg) |
| 355 | |
| 356 | if bom_found: |
no test coverage detected