как бороться с юникодом в мако? - PullRequest
13 голосов
/ 26 июля 2010

Я постоянно получаю эту ошибку, используя mako:

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

Я сказал Мако, что использую юникод любым возможным способом:

    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)

Все мои файлы шаблонов начинаются с:

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

и внутри них все строки-префиксы имеют префикс "u". Я знаю, что параметр self.stuff содержит строки в юникоде, но способ, которым я создаю экземпляры объектов mako, должен позаботиться об этом (иначе, для чего эти аргументы хороши?) Я что-то забыл сделать?

Еще один вопрос: в чем смысл encoding_errors = 'replace'?

= EDIT = Я оставил только одну строку Unicode, и это обратная связь:

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)

Ответы [ 3 ]

13 голосов
/ 27 июля 2010

наконец я сохранил свои шаблоны в юникоде, на самом деле (я думаю) utf-16 вместо utf-8. их размер на диске удвоился, и Мако начал жаловаться на «CompileException (« операция декодирования Unicode при кодировании 'utf-8' bla bla »), поэтому я изменил первую строку во всех из них:

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

и удалены все константы ".decode ('utf-8')" - все еще имеют префикс "u".

инициализация в Python теперь такова:

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

это работает сейчас. Похоже, что utf-8 был неправильным выбором (или моя неспособность сохранить шаблоны в utf-8), но я не могу объяснить, почему это работает с eclipse / pydev.

1 голос
/ 21 мая 2013

Ради Google:

Мако вызывает исключение mako.exceptions.CompileException: Unicode decode operation of encoding 'ascii' failed in file и т. Д., Когда ваш файл шаблона содержит символы, отличные от ascii, и когда в файл не записана спецификация Unicode.Вам необходимо вручную добавить спецификацию (это не делается автоматически, по крайней мере, в моем текстовом редакторе), чтобы это:

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

стало следующим:

$file test.htm
test.htm: HTML document, UTF-8 Unicode (with BOM) text
0 голосов
/ 11 августа 2014

Ни одно из этих предложений (включая принятый ответ) не работает во всех случаях, особенно если шаблон mako отображает содержимое (например, $ {value | n}), где значение содержит символы не ascii.

Это потому, что по умолчанию mako оборачивает юникод (foo) вокруг любых значений в сгенерированных скомпилированных шаблонах, что все равно приведет к:

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

Единственный надежный способ заставить mako обрабатывать юникод в python2 - это заменить обработчик по умолчанию ('unicode'), например:

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