2010-07-26 42 views
13

constantemente consigo este error utilizando mako:cómo lidiar con unicode en mako?

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 6: ordinal not in range(128) 

le he dicho a mako estoy usando Unicode de cualquier manera posible:

mylookup = TemplateLookup(
     directories=['plugins/stl/templates'], 
     input_encoding='utf-8', 
     output_encoding='utf-8', 
     default_filters=['decode.utf8'], 
     encoding_errors='replace') 

    self.template = Template(self.getTemplate(), lookup=mylookup, 
     module_directory=tempfile.gettempdir(), 
     input_encoding='utf-8', 
     output_encoding='utf-8', 
     default_filters=['decode.utf8'], 
     encoding_errors='replace') 

    html = self.template.render_unicode(data=self.stuff) 

Todos mis archivos de plantilla comienza con:

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

y, dentro de ellos, todas las cadenas de costant llevan el prefijo "u". Sé que el parámetro self.stuff contiene cadenas de caracteres unicode, pero la forma en que instanciar los objetos de mako debe ocuparse de ello (de lo contrario, ¿para qué sirven esos argumentos?). ¿Hay algo que olvidé hacer?

Una pregunta más: ¿cuál es el punto de encoding_errors = 'replace'?

= edit = Salí de una única cadena Unicode y este es el rastreo:

Traceback (most recent call last): 
    File "C:\My Dropbox\src\flucso\src\plugins\stl\main.py", line 240, in updateView 
    flags=self.makoflags) 
    File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\template.py", line 198, in render_unicode 
    as_unicode=True) 
    File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 403, in _render 
    _render_context(template, callable_, context, *args, **_kwargs_for_callable(callable_, data)) 
    File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 434, in _render_context 
    _exec_template(inherit, lclcontext, args=args, kwargs=kwargs) 
    File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 457, in _exec_template 
    callable_(context, *args, **kwargs) 
    File "memory:0x41317f0", line 89, in render_body 
    File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 278, in <lambda> 
    return lambda *args, **kwargs:callable_(self.context, *args, **kwargs) 
    File "FriendFeed_mako", line 49, in render_inlist_entry 
    File "C:\Python26\lib\encodings\utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u263c' in position 8: ordinal not in range(128) 
+0

esto es bueno: me deshice de código de dejar un solo $ {unicode_string_value.decode todos mis plantillas ('UTF-8')} y , ¿adivina qué? mako todavía plantea la excepción ... –

+0

muestra el traceback –

+0

oh y olvidé mencionar que si ejecuto/depuro la aplicación dentro de Eclipse + PyDev, mako no informa ningún error y el html resultante está bien. el inicio desde una consola o un acceso directo da como resultado el error Unicode. –

Respuesta

13

finalmente salvaron mis plantillas en Unicode, en realidad (supongo) UTF-16 en lugar de UTF-8. su tamaño en el disco se duplicó y marrajo comenzó a quejarse de un "CompileException (" operación de descodificación Unicode de codificación 'UTF-8' bla bla", por lo que cambió la primera línea en todos ellos en:

## -*- coding: utf-16 -*- 

y eliminado todos los ".decode ('UTF-8')" - cadenas constantes siguen el prefijo "u"

las inicializaciones en pitón ahora son:

mylookup = TemplateLookup(
    directories=['plugins/stl/templates'], 
    input_encoding='utf-16', 
    output_encoding='utf-16', 
    encoding_errors='replace') 

self.template = Template(self.getTemplate(), lookup=mylookup, 
    module_directory=tempfile.gettempdir(), 
    input_encoding='utf-16', 
    output_encoding='utf-16', 
    encoding_errors='replace') 

funciona ahora se parece.. utf-8 fue la elección incorrecta (o mi incapacidad para guardar el templ ates en utf-8), pero no puedo explicar por qué funcionó de eclipse/pydev.

1

Por el bien de los empleados de Google:

Mako genera una excepción mako.exceptions.CompileException: Unicode decode operation of encoding 'ascii' failed in file, etc., cuando el archivo de plantilla comprende caracteres no ASCII, Unicode y cuando la lista de materiales no se escribe en el archivo. Es necesario añadir manualmente la lista de materiales (esto no se hace de forma automática, al menos en mi editor de texto), por lo que este:

$file test.htm 
test.htm: HTML document, UTF-8 Unicode text 

se convierte en esto:

$file test.htm 
test.htm: HTML document, UTF-8 Unicode (with BOM) text 
+1

Esto ya no es cierto. Si el archivo es utf-8 sin BOM y input_encoding es 'utf-8', al menos funcionará con Template, no intentó TemplateLookup. – Javier

0

Ninguna de estas sugerencias (incluyendo el respuesta aceptada) funcionan en todos los casos, específicamente cuando la plantilla de mako representa el contenido (por ej., $ {value | n}) donde el valor contiene caracteres no ascii.

Esto es porque por defecto marrajo envuelve Unicode (foo) en torno a los valores de las plantillas compiladas generados, que todavía dará lugar a:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128) 

La única forma segura de hacer Unicode mango marrajo en python2 es para reemplazar el valor por defecto ('unicode') manipulador, así:

def handle_unicode(value): 
    if isinstance(value, basestring): 
     return unicode(value.decode('ascii', errors='ignore')) 
    return unicode(value) 


...  

lookup = TemplateLookup(
    directories=[self._root.template_path], 
    imports=['from utils.view import handle_unicode'], 
    default_filters=["handle_unicode"] 
) 

... 

template = self._lookup.get_template(self.template()) 
rtn = template.render(request=self.request) 
Cuestiones relacionadas