Python os.stat y nombres de archivos Unicode

En mi aplicación Django, un usuario ha cargado un archivo con un carácter Unicode en el nombre.

Cuando estoy descargando archivos, estoy llamando:

os.path.exists(media) 

para probar que el archivo está ahí. Esto, a su vez, parece llamar

 st = os.stat(path) 

Que luego explota con el error:

UnicodeEncodeError: el codec ‘ascii’ no puede codificar el carácter u ‘\ xcf’ en la posición 92: ordinal no está dentro del rango (128)

¿Qué puedo hacer sobre esto? ¿Hay una opción para path.exists para manejarlo?

Actualización: En realidad, todo lo que tenía que hacer era codificar el argumento para existir, es decir.

 os.path.exists(media.encode('utf-8') 

Gracias a todos los que respondieron.

Supongo que estás en Unix. Si no, recuerda decir en qué sistema operativo estás.

Asegúrese de que su configuración regional esté establecida en UTF-8. Todos los sistemas Linux modernos lo hacen de forma predeterminada, generalmente configurando la variable de entorno LANG en “en_US.UTF-8” u otro idioma. Además, asegúrese de que sus nombres de archivo estén codificados en UTF-8.

Con ese conjunto, no es necesario meterse con las codificaciones para acceder a los archivos en cualquier idioma, incluso en Python 2.x.

 [~/test] echo $LANG en_US.UTF-8 [~/test] echo testing > 漢字[~/test] python2.6 Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> os.stat("漢字") posix.stat_result(st_mode=33188, st_ino=548583333L, st_dev=2049L, st_nlink=1, st_uid=1000, st_gid=1000, st_size=8L, st_atime=1263634240, st_mtime=1263634230, st_ctime=1263634230) >>> os.stat(u"漢字") posix.stat_result(st_mode=33188, st_ino=548583333L, st_dev=2049L, st_nlink=1, st_uid=1000, st_gid=1000, st_size=8L, st_atime=1263634240, st_mtime=1263634230, st_ctime=1263634230) >>> open("漢字").read() 'testing\n' >>> open(u"漢字").read() 'testing\n' 

Si esto no funciona, ejecute “locale”; Si los valores son “C” en lugar de en_US.UTF-8, es posible que no tenga la configuración regional instalada correctamente.

Si está en Windows, creo que los nombres de archivo Unicode siempre deberían funcionar (al menos para los módulos os / posix), ya que la API del archivo Unicode en Windows es compatible de forma transparente.

Ninguna de estas soluciones funcionó para mí. Sin embargo, encontré la (a?) Solución. Todavía hay otro lugar en la configuración de Apache donde uno tiene que agregar la configuración regional si utiliza WSGI. Los documentos oficiales están aquí . Agregue las siguientes dos líneas a /etc/apache2/envvars (en Ubuntu):

 export LANG='en_US.UTF-8' export LC_ALL='en_US.UTF-8' 

Luego reinicie el servidor. Esto solucionó mi problema.

Codificar a la encoding del sistema de archivos antes de llamar. Ver el módulo de locale .

Cambie su servidor http para usar la configuración regional UTF-8. Por ejemplo, uso apache2 en CentOS. Cambié la configuración regional / etc / sysconfig / httpd mediante HTTPD_LANG:

 # CentOS use /etc/sysconfig/httpd to config environment variables. # # By default, the httpd process is started in the C locale; to # change the locale in which the server runs, the HTTPD_LANG # variable can be set. # # HTTPD_LANG=C HTTPD_LANG=en_US.UTF-8 # you can change to your locale. 

Es fácil obtener este tipo de error al ejecutar el servicio (Ej .: gunicorn) desde Upstart.

Para arreglar eso, establece env en el archivo upstart:

 env LANG=en_US.UTF-8 env LC_CTYPE=en_US.UTF-8 env LC_ALL=en_US.UTF-8