¿Qué codificaciones de archivos son compatibles con los archivos fuente de Python 3?

Antes de que me digas que lea PEP 0263 , sigue leyendo …

No puedo encontrar ninguna documentación que detalle qué codificaciones de archivos son compatibles con los archivos de origen de Python 3 .

He encontrado cientos (¿miles?) De preguntas, respuestas, publicaciones, correos electrónicos, etc. sobre cómo declarar, en la parte superior de su archivo fuente, la encoding de ese archivo fuente, pero ninguna de ellas responde a mi pregunta. Tenga paciencia conmigo e imagine que hace (o realmente intenta) lo siguiente:

  1. Abra el Bloc de notas (estoy usando el antiguo Bloc de notas normal en Windows 7, pero dudo que importe; estoy seguro de que su editor superior puede hacer algo similar).
  2. Escriba su línea favorita de código Python (utilicé print( 'Hello, world!' ) )
  3. Seleccione “Archivo” -> “Guardar”
  4. Seleccione una carpeta y un nombre de archivo (usé “E: \ Temp \ hello.py”)
  5. Cambie la configuración de “Codificación:” del valor predeterminado “ANSI” a “Unicode”
  6. Presiona “guardar”
  7. Abra un símbolo del sistema, cambie a la carpeta que contiene su nuevo archivo e intente ejecutarlo

Aquí está la salida que recibo:

 E:\Temp>python --version Python 3.4.1 E:\Temp>python "hello.py" File "hello.py", line 1 SyntaxError: Non-UTF-8 code starting with '\xff' in file hello.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details 

Ahora, cuando abro este mismo archivo en Notepad ++ y veo el menú “Codificación”, tiene seleccionada la opción “Codificar en UCS-2 Little Endian”. Wikipedia me dice que esto es básicamente la encoding UTF-16. Lo que sea. Realmente no me importa. Más investigaciones revelan que mi editor ha insertado una lista de materiales de dos bytes (marca de orden de bytes) con un valor de ‘\ xff \ xfe’ en la parte frontal del archivo para indicar la encoding del archivo. Así que al menos sé de dónde proviene el código ‘\ xff’ del que se queja Python.

Así que voy y leo PEP 0263 , y todo lo demás relacionado con él, en la web, e bash agregar un comentario como este a la primera línea del archivo.

 # coding: utf-16 

con todo tipo de valores diferentes para la encoding, y nada ayuda. Pero no puede ayudar, ¿verdad? Porque Python ni siquiera está llegando a mi statement de encoding; ¡Se está ahogando en el primer byte del archivo fuente!

Así que lo que realmente quiero saber es …

  1. ¿Por qué el intérprete de Python 3 no puede leer este archivo?
  2. Si “Unicode” o “UCS-2 Little Endian” o “UTF-16” o lo que sea ​​no es compatible, ¿qué es?

PD: incluso encontré otra pregunta en StackOverflow que parece ser el problema exacto que tengo, pero se cerró, erróneamente en mi opinión, como un duplicado. 🙁

— EDITAR —

Alguien me preguntó por mis “opciones comstackdas”. Aquí hay algunos resultados. Tal vez te ayude?

 E:\Temp>python Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import sysconfig >>> print( sysconfig.get_config_vars() ) {'EXT_SUFFIX': '.pyd', 'srcdir': 'C:\\Python34', 'py_version_short': '3.4', 'base': 'C:\\Python34', 'prefix': 'C:\\Python34', 'projectbase': 'C:\\Python34', 'INCLUDEPY': 'C:\\Python34\\Include', 'platbase': 'C:\\Python34', 'py_version_nodot': '34', 'exec_prefix': 'C:\\Python34', 'EXE': '.exe', 'installed_base': 'C:\\Python34', 'SO': '.pyd', 'installed_platbase': 'C:\\Python34', 'VERSION': '34', 'BINLIBDEST': 'C:\\Python34\\Lib', 'LIBDEST': 'C:\\Python34\\Lib', 'userbase': 'C:\\Users\\alonghi\\AppData\\Roaming\\Python', 'py_version': '3.4.1', 'abiflags': '', 'BINDIR': 'C:\\Python34'} >>> 

Una encoding fuente debe ser:

  1. Una encoding soportada por la versión de Python en cuestión. (Esto varía según la versión y la plataforma, por ejemplo, solo obtiene mbcs en Windows).

  2. Apenas compatible con ASCII, lo suficiente para que la # coding: statement pueda leerse usando ascii que es la fuente de encoding inicial antes de que se lea cualquier statement. Ver PEP0263 ítem ‘Conceptos’ 1.

La encoding que Windows llama erróneamente “Unicode”, UTF-16LE, no es compatible con ASCII (y en general es un conjunto de problemas que debe tratar de evitar usar). Python necesitaría un soporte especial específico de encoding para detectar archivos de origen UTF-16 y esta característica ha sido rechazada por ahora.

La # coding: que debe usar es casi invariablemente UTF-8.