Image

Imageice_b wrote in Imageru_python

Mako Templates. Минорный баг в модуле pygen

Скорее даже простой недочет, но от этого не легче.
Дело в следующем. Когда в контексте шаблона присутствуют идентификаторы, имена которых начинаются с else, elif, try, except, finally, while, for, def и class генератор кода начинает путаться в отступах. Получается следующее:
def render_body(context,**pageargs):
    context.caller_stack.push_frame()
    try:
        __M_locals = dict(pageargs=pageargs)
    except_val = context.get('except_val', UNDEFINED)
    # SOURCE LINE 1
    context.write(u'Internal Server Error')
    context.write(unicode(except_val))
    return ''
    finally:
        context.caller_stack.pop_frame()
и
def render_body(context,**pageargs):
    context.caller_stack.push_frame()
    try:
        __M_locals = dict(pageargs=pageargs)
        exc_val = context.get('exc_val', UNDEFINED)
        # SOURCE LINE 1
        context.write(u'Internal Server Error')
        context.write(unicode(exc_val))
        return ''
    finally:
        context.caller_stack.pop_frame()

Конечно, можно просто использовать префиксы и сокращения, но на мой взгляд это будет немотивированным ограничением. Особенно когда задача заключается лишь в организации проверки идентификатора на правильную форму записи имени переменной в Python.
Стоит лишь немного подправить регекспы в mako.pygen.PythonPrinter.writeline и в mako.pygen.PythonPrinter._is_unindentor, дописав в них
(base_regexp) [^\da-zA-Z_]+

Возможно я что-то упустил, но на первый взгляд работает.
Думаю, тикет в проект засабмитеть стоит в любом случае. Возможно обратят внимание.
Вот, если можно так сказать, "патч". С той версии, которой пользуюсь я:
10c10,13
< from StringIO import StringIO
---
> try:
>     from cStringIO import StringIO
> except ImportError:
>     from StringIO import StringIO
105c108
<             match = re.match(r"^\s*(if|try|elif|while|for)", line)
---
>             match = re.match(r"^\s*(if|try|elif|while|for)[^\da-zA-Z_]+", line)
116c119
<                 m2 = re.match(r"^\s*(def|class|else|elif|except|finally)", line)
---
>                 m2 = re.match(r"^\s*(def|class|else|elif|except|finally)[^\da-zA-Z_]", line)
141c144
<         match = re.match(r"^\s*(else|elif|except|finally)", line)
---
>         match = re.match(r"^\s*(else|elif|except|finally)[^\da-zA-Z_]+", line)