¿Cómo conseguir IDLE para aceptar pegar de caracteres Unicode?

A menudo, cuando trabajo interactivamente en IDLE, me gustaría pegar una cadena Unicode en la ventana IDLE. Parece que se pega correctamente pero genera un error inmediatamente. No tiene problemas para mostrar el mismo carácter en la salida.

>>> c = u'ĉ' Unsupported characters in input >>> print u'\u0109' ĉ 

Sospecho que la ventana de entrada, como la mayoría de los progtwigs de Windows, usa UTF-16 internamente y no tiene problemas para manejar el conjunto completo de Unicode; el problema es que IDLE insiste en forzar todas las entradas a la página de códigos de mbcs predeterminada, y cualquier cosa que no esté en esa página se rechaza.

¿Hay alguna forma de configurar o convencer a IDLE para que acepte el conjunto completo de caracteres Unicode como entrada?

Python 3.2 maneja esto mucho mejor y no tiene problemas con todo lo que le ofrezco.

Sé que puedo simplemente guardar el código en un archivo en UTF-8 e importarlo, pero quiero poder trabajar con caracteres Unicode en la ventana interactiva.

Finalmente me di cuenta de una manera. Ya que las fonts a IDLE son parte de la distribución, puede hacer un par de ediciones rápidas para habilitar la capacidad. Los archivos normalmente se encontrarán en C:\Python27\Lib\idlelib .

El primer paso es evitar que IDLE intente codificar todos esos agradables caracteres Unicode en un conjunto de caracteres que no los puede manejar. Esto es controlado por IOBinding.py . Edite el archivo, busque la sección después de if sys.platform == 'win32': y comente esta línea:

 #encoding = locale.getdefaultlocale()[1] 

Ahora agregue esta línea después de esto:

 encoding = 'utf-8' 

Esperaba que hubiera una forma de anular esto con una variable de entorno o algo así, pero getdefaultlocale llama directamente a una función de Win32 que obtiene la encoding de mbcs de Windows configurada globalmente.

Esta es la mitad de la batalla, ahora necesitamos que el intérprete de línea de comandos reconozca que los bytes de entrada están codificados en UTF-8. No parecía que hubiera una forma de pasar una encoding al intérprete, así que se me ocurrió la madre de todos los hackers. Tal vez alguien con un poco más de paciencia puede encontrar una mejor manera, pero esto funciona por ahora. La entrada se procesa en PyShell.py , en la función de runsource . Cambia lo siguiente:

  if isinstance(source, types.UnicodeType): from idlelib import IOBinding try: source = source.encode(IOBinding.encoding) except UnicodeError: self.tkconsole.resetoutput() self.write("Unsupported characters in input\n") return 

A:

  from idlelib import IOBinding # line moved if isinstance(source, types.UnicodeType): try: source = source.encode(IOBinding.encoding) except UnicodeError: self.tkconsole.resetoutput() self.write("Unsupported characters in input\n") return source = "#coding=%s\n%s" % (IOBinding.encoding, source) # line added 

Estamos aprovechando PEP 263 para especificar la encoding de cada línea de entrada proporcionada al intérprete.

Actualización : en Python 2.7.10 ya no es necesario realizar el cambio en PyShell.py , ya funciona correctamente si la encoding se establece en utf-8 . Desafortunadamente, no he encontrado una manera de evitar el cambio en IOBinding.py .