2010-07-26 9 views
13

Je reçois constamment cette erreur en utilisant mako:comment faire face à unicode dans mako?

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

Je l'ai dit Mako J'utilise unicode dans toutes les manières possibles:

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) 

Tous mes fichiers de modèle commence par:

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

et, à l'intérieur, toutes les chaînes coûteuses sont préfixées avec "u". Je sais que le paramètre self.stuff contient des chaînes unicode, mais la façon dont j'instancie les objets mako devrait en tenir compte (sinon à quoi servent ces arguments?). Y a-t-il quelque chose que j'ai oublié de faire?

Encore une question: quel est le point de encoding_errors = 'replace'?

= EDIT = je suis parti une seule chaîne de caractères Unicode, ce qui est le retraçage:

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

c'est agréable: je me suis débarrassé de tous mes modèles de code en laissant un seul $ {unicode_string_value.decode ('utf-8')} et , devine quoi? mako soulève toujours l'exception ... –

+0

s'il vous plaît montrer le retraçage –

+0

oh et j'ai oublié de mentionner que si je cours/débogue l'application dans Eclipse + PyDev, mako ne signale aucune erreur et le html résultant est ok. le lancement à partir d'une console ou d'un raccourci entraîne l'erreur Unicode. –

Répondre

13

finalement je sauvé mes modèles dans unicode, en fait (je suppose) utf-16 au lieu de utf-8. leur taille sur le disque double et Mako a commencé à se plaindre d'un « CompileException (» opération de décodage Unicode de codage bla « utf-8 » bla », donc je changé la première ligne tous dans:

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

et supprimé tous les ".decode ('utf-8')" - chaînes constantes sont toujours préfixé par "u"

les initialisations en python sont maintenant:

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

cela fonctionne maintenant ressemble.. utf-8 était le mauvais choix (ou mon incapacité à sauver le templ ates dans utf-8), mais je ne peux pas expliquer pourquoi cela a fonctionné depuis eclipse/pydev.

1

Par souci de Googlers:

Mako déclenche une exception mako.exceptions.CompileException: Unicode decode operation of encoding 'ascii' failed in file, etc., lorsque votre fichier modèle comprend des caractères non-ascii, et lorsque la nomenclature Unicode n'est pas écrit dans le fichier. Vous devez ajouter manuellement la nomenclature (ce ne se fait pas automatiquement, au moins dans mon éditeur de texte), de sorte que celle-ci:

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

devient ceci:

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

Ce n'est plus vrai. Si le fichier est utf-8 sans BOM et que le paramètre input_encoding est 'utf-8', il fonctionnera au moins avec Template, n'a pas essayé TemplateLookup. – Javier

0

Aucune de ces suggestions (y compris la réponse acceptée) fonctionne dans tous les cas, en particulier lorsque le modèle mako rend le contenu (par exemple, $ {value | n}) où la valeur contient des caractères non ascii.

En effet, par défaut mako enveloppe unicode (foo) autour des valeurs dans les générés modèles compilés, ce qui entraînera encore:

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

La seule façon infaillible de faire unicode poignée Mako dans python2 est pour remplacer la valeur par défaut ('unicode') gestionnaire, comme ceci:

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) 
Questions connexes