meaning python python-2.7 encoding character-encoding

python - meaning - obtener la codificación especificada en la línea mágica/shebang(desde dentro del módulo)



shebang meaning (1)

Pediría prestada la función Python 3 tokenize.detect_encoding() en Python 2, ajustada un poco para que coincida con las expectativas de Python 2. Cambié la firma de la función para aceptar un nombre de archivo y dejé de incluir las líneas leídas hasta el momento; no los necesita para su uso:

import re from codecs import lookup, BOM_UTF8 cookie_re = re.compile(r''^[ /t/f]*#.*?coding[:=][ /t]*([-/w.]+)'') blank_re = re.compile(br''^[ /t/f]*(?:[#/r/n]|$)'') def _get_normal_name(orig_enc): """Imitates get_normal_name in tokenizer.c.""" # Only care about the first 12 characters. enc = orig_enc[:12].lower().replace("_", "-") if enc == "utf-8" or enc.startswith("utf-8-"): return "utf-8" if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or / enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): return "iso-8859-1" return orig_enc def detect_encoding(filename): bom_found = False encoding = None default = ''ascii'' def find_cookie(line): match = cookie_re.match(line) if not match: return None encoding = _get_normal_name(match.group(1)) try: codec = lookup(encoding) except LookupError: # This behaviour mimics the Python interpreter raise SyntaxError( "unknown encoding for {!r}: {}".format( filename, encoding)) if bom_found: if encoding != ''utf-8'': # This behaviour mimics the Python interpreter raise SyntaxError( ''encoding problem for {!r}: utf-8''.format(filename)) encoding += ''-sig'' return encoding with open(filename, ''rb'') as fileobj: first = next(fileobj, '''') if first.startswith(BOM_UTF8): bom_found = True first = first[3:] default = ''utf-8-sig'' if not first: return default encoding = find_cookie(first) if encoding: return encoding if not blank_re.match(first): return default second = next(fileobj, '''') if not second: return default return find_cookie(second) or default

Al igual que la función original, la función anterior lee dos líneas como máximo desde el archivo fuente, y generará una excepción SyntaxError si la codificación en la cookie no es válida o no es UTF-8 mientras está presente una BOM UTF-8.

Manifestación:

>>> import tempfile >>> def test(contents): ... with tempfile.NamedTemporaryFile() as f: ... f.write(contents) ... f.flush() ... return detect_encoding(f.name) ... >>> test(''# -*- coding: utf-8 -*-/n'') ''utf-8'' >>> test(''#!/bin/env python/n# -*- coding: latin-1 -*-/n'') ''iso-8859-1'' >>> test(''import this/n'') ''ascii'' >>> import codecs >>> test(codecs.BOM_UTF8 + ''import this/n'') ''utf-8-sig'' >>> test(codecs.BOM_UTF8 + ''# encoding: latin-1/n'') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 5, in test File "<string>", line 37, in detect_encoding File "<string>", line 24, in find_cookie SyntaxError: encoding problem for ''/var/folders/w0/nl1bwj6163j2pvxswf84xcsjh2pc5g/T/tmpxsqH8L'': utf-8 >>> test(''# encoding: foobarbaz/n'') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 5, in test File "<string>", line 37, in detect_encoding File "<string>", line 18, in find_cookie SyntaxError: unknown encoding for ''/var/folders/w0/nl1bwj6163j2pvxswf84xcsjh2pc5g/T/tmpHiHdG3'': foobarbaz

Si especifico la codificación de caracteres (como lo sugiere PEP 263 ) en la "línea mágica" o shebang de un módulo python como

# -*- coding: utf-8 -*-

¿Puedo recuperar esta codificación desde ese módulo?

(Trabajando en Windows 7 x64 con Python 2.7.9)

Intenté (sin éxito) recuperar la codificación predeterminada o shebang

# -*- coding: utf-8 -*- import sys from shebang import shebang print "sys.getdefaultencoding():", sys.getdefaultencoding() print "shebang:", shebang( __file__.rstrip("oc"))

rendirá:

sys.getdefaultencoding (): ascii

shebang: Ninguno

(lo mismo para iso-8859-1)