2010-07-26 5 views
13

ich diesen Fehler ständig mit mako erhalten:wie mit Unicode in Mako umgehen?

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

I mako in jeder möglichen Weise verwende ich Unicode gesagt habe:

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) 

Alle meine Template-Dateien beginnt mit:

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

und in ihnen alle Zeichenfolgen mit Präfix "u". Ich weiß, dass der Parameter self.stuff Unicode-Strings enthält, aber die Art, wie ich die Mako-Objekte instanziiere, sollte sich darum kümmern (sonst, wofür sind diese Argumente gut?). Gibt es etwas, was ich vergessen habe?

Eine weitere Frage: Was ist der Sinn von encoding_errors = 'replace'?

= EDIT = verließ ich nur ein einziges Unicode-String und das ist die Traceback:

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

das ist schön: der Standard ('Unicode') Handler, wie diese zu ersetzen habe ich loswerden all Code einen einzelnen $ {unicode_string_value.decode ließe meine Vorlagen ('utf-8')} und , erraten Sie, was? mako erhöhen noch die Ausnahme ... –

+0

zeigen Sie bitte die Zurückverfolgungs –

+0

oh und ich vergaß zu erwähnen, dass, wenn ich/debug die Anwendung in Eclipse + PyDev laufen, mako keine Fehler meldet und die resultierende HTML ist in Ordnung. Starten von einer Konsole oder einer Verknüpfung führt zu dem Unicode-Fehler. –

Antwort

13

schließlich ich meine Vorlagen in Unicode gespeichert, tatsächlich (ich glaube) utf-16 anstelle von utf-8. ihre Größe auf der Festplatte verdoppelt und mako gestartet von einem „CompileException (“ Unicode Decodierungsoperation beschweren der Codierung ‚utf-8‘ bla bla“, also habe ich die erste Zeile in allen von ihnen in:

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

und entfernt alle ".decode ('utf-8')" - sind konstante Strings durch "u" noch voran

die Initialisierungen in python sind jetzt:

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') 

es funktioniert jetzt aussieht.. utf-8 war die falsche Wahl (oder meine Unfähigkeit, das Templ zu retten ates in utf-8), aber ich kann nicht erklären, warum es von eclipse/pydev funktioniert hat.

1

Aus Gründen der Googler:

Mako löst eine Ausnahme mako.exceptions.CompileException: Unicode decode operation of encoding 'ascii' failed in file, etc., wenn Sie Ihre Template-Datei Zeichen nicht-ascii begreift, und wenn die Unicode-BOM nicht in die Datei geschrieben wird. Sie müssen manuell die Stückliste hinzufügen (dies wird nicht automatisch, zumindest in meinem Texteditor gemacht), so dass diese:

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

wird daraus:

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

Dies ist nicht mehr wahr. Wenn die Datei utf-8 ohne BOM ist und die Eingabecodierung 'utf-8' ist, wird sie zumindest mit der Vorlage funktionieren, nicht mit TemplateLookup. – Javier

0

Keiner dieser Vorschläge (einschließlich der akzeptierte Antwort) funktionieren in allen Fällen, insbesondere dort, wo die Mako-Vorlage Inhalt (z. B. $ {Wert | n}) darstellt, wobei der Wert nicht-ASCII-Zeichen enthält.

Dies liegt daran, dass standardmäßig mako Unicode (foo) um beliebige Werte in den erzeugten kompilierten Templates wickelt, die sich noch in resultieren:

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

Der einzig sichere Weg, um mako handle Unicode in python2 ist

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)