[pyar] Problema con encoding

Andrés Gattinoni andresgattinoni en gmail.com
Mar Jul 26 16:20:33 ART 2011


2011/7/26 Mariano Reingart <reingart en gmail.com>:
>> Lo que yo pienso es, si la consola (que la tengo en utf-8) puede
>> interpretar bien los caracteres cuando hago el print.
>> Por qué no puedo escribirlos directamente (o traducidos a lo que
>> corresponda) en el archivo?
>
> Me parece que estas mezclando codecs y encode, calculo que si abris
> con codecs le mandas unicodes directamente (sin "encodificar").
> Si abris con el open comun, tenes que mandar string ("encodificando"
> los unicodes al encoding que elijas).
>
> Hace un print type(rendered) para ver que tipo es, y dependiendo del
> caso, lo convertis a unicode o string segun el parrafo anterior.

El print type(rendered) me muestra que es un string. Probé de las dos
formas pasándoselo a unicode() y llamando a .encode('utf8') y el error
es el mismo.

# -*- coding: utf-8 -*-
import sys
import codecs
from gluon import template

def render (filename, template_file, data):
    tplfile = codecs.open(template_file, 'r', 'utf-8')
    html = tplfile.read()
    tplfile.close()
    #f = codecs.open(filename, 'w', 'utf-8')
    #f = open(filename, 'w')
    rendered = template.render(html, context=data)
    print type(rendered)
    #rendered = unicode(rendered)
    rendered = rendered.encode('utf8')
    print rendered

$ python process.py
<type 'str'>
Traceback (most recent call last):
  File "process.py", line 69, in <module>
    sys.exit(main(sys.argv))
  File "process.py", line 66, in main
    render('./index.html', 'templates/index.tpl', data)
  File "process.py", line 15, in render
    rendered = unicode(rendered)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position
3352: ordinal not in range(128)

$ python process.py
<type 'str'>
Traceback (most recent call last):
  File "process.py", line 69, in <module>
    sys.exit(main(sys.argv))
  File "process.py", line 66, in main
    render('./index.html', 'templates/index.tpl', data)
  File "process.py", line 16, in render
    rendered = rendered.encode('utf8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position
3352: ordinal not in range(128)

Que a su vez es el mismo error que cuando hago f.write(rendered) en un
archivo abierto con codecs.open() como UTF-8:

$ python process.py
<type 'str'>
Traceback (most recent call last):
  File "process.py", line 69, in <module>
    sys.exit(main(sys.argv))
  File "process.py", line 66, in main
    render('./index.html', 'templates/index.tpl', data)
  File "process.py", line 18, in render
    f.write(rendered)
  File "/usr/lib/python2.7/codecs.py", line 691, in write
    return self.writer.write(data)
  File "/usr/lib/python2.7/codecs.py", line 351, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position
3352: ordinal not in range(128)

Entonces, luego de estas pruebas tengo lo siguiente:

- rendered es un string que debería estar en UTF-8 (pero no sé
exactamente en qué está, puedo averiguarlo?), que si lo guardo en un
archivo (con un simple open() y write() o redirigiendo stdout a un
archivo), el archivo me queda como un montón de datos binarios que los
editores no pueden reconocer

- si trato de encodear de cualquier manera el rendered a UTF-8 (sea
usando la función unicode(), o .encode('utf8') o escribiéndolo en un
archivo abierto con codecs.open), pincha porque hay un caracter que no
puede convertir

- ese caracter, ya he comprobado, es una é (e con tílde)... si
reemplazo la "é" por una "e", todas las opciones de codificación
funcionan (unicode, decode y codecs.open)... lo único que pasa a no
funcionar en este caso es escribir directamente en un archivo el
contenido de la variable rendered sin encodearla.

Quizás mi problema es no entender verdaderamente cómo está codificado
ese string de la variable rendered que obtengo del método
template.render() de web2py.



More information about the pyar mailing list