Python 如何调试Mako模板?

Python 如何调试Mako模板?,python,debugging,templates,jinja2,mako,Python,Debugging,Templates,Jinja2,Mako,到目前为止,我发现当Mako模板编码不正确时,不可能产生可用的回溯 除了对每一行代码进行迭代之外,还有什么方法可以调试模板吗?我将它们分解成若干部分,然后在发现问题后重新组装这些部分 不太好,但是很难判断一个大而复杂的模板出了什么问题。Mako实际上提供了一个: 使用flask_mako,我发现跳过TemplateError生成并忽略异常更容易。也就是说,在flask_mako.py中,注释掉导致TemplateError的部分,然后只进行提升: def _render(template, co

到目前为止,我发现当Mako模板编码不正确时,不可能产生可用的回溯


除了对每一行代码进行迭代之外,还有什么方法可以调试模板吗?

我将它们分解成若干部分,然后在发现问题后重新组装这些部分

不太好,但是很难判断一个大而复杂的模板出了什么问题。

Mako实际上提供了一个:


使用flask_mako,我发现跳过TemplateError生成并忽略异常更容易。也就是说,在flask_mako.py中,注释掉导致TemplateError的部分,然后只进行提升:

def _render(template, context, app):
 """Renders the template and fires the signal"""
app.update_template_context(context)
try:
    rv = template.render(**context)
    template_rendered.send(app, template=template, context=context)
    return rv
except:
    #translated = TemplateError(template)                                                                                                                 
    #raise translated                                                                                                                                     
    raise
}

然后您将看到一个常规的python异常,该异常与模板中的行号一起导致问题。

查看源代码,我发现一个名为
MAKO\u TRANSLATE\u EXCEPTIONS的未记录配置参数


在您的Flask应用程序配置中将此设置为
False
,您将从模板中获得很好的异常。这与@Mariano建议的一样,无需编辑源代码。显然,这个参数是在Mariano的答案之后添加的。

将两个最重要的答案与我自己的特殊酱汁结合起来:

from flask.ext.mako import render_template as render_template_1
from mako import exceptions

app.config['MAKO_TRANSLATE_EXCEPTIONS'] = False    # seems to be necessary

def render_template(*args, **kwargs):
    kwargs2 = dict(**kwargs)
    kwargs2['config'] = app.config     # this is irrelevant, but useful
    try:
        return render_template_1(*args, **kwargs2)
    except:
        if app.config.get('DEBUG'):
            return exceptions.html_error_template().render()
        raise
它包装了股票“render_template”功能:

  • 捕获异常,以及
    • 如果正在调试,则呈现回溯跟踪
    • 如果未调试,请再次引发异常,以便将其记录下来
  • 使配置可从页面访问(不相关)

    • 我对Mako的主要不满是很难看到模板中发生了什么。由于模板代码是内存中的可运行对象,因此调试器无法查看它

      一种解决方案是将模板代码写入文件,并将此文件作为标准python模块重新运行模板。然后你可以调试到你的心内容

      例如:

      import sys
      from mako import exceptions, template 
      from mako.template import DefTemplate
      from mako.runtime import _render
      
      <Do Great Stuff>
      
      try:
          template.render(**arguments))
      except:
          # Try to re-create the error using a proper file template
          # This will give a clearer error message.
          with open('failed_template.py', 'w') as out:
              out.write(template._code)
          import failed_template
          data = dict(callable=failed_template.render_body, **arguments)
          try:
              _render(DefTemplate(template, failed_template.render_body),
                      failed_template.render_body,
                      [],
                      data)
          except:
              msg = '<An error occurred when rendering template for %s>\n'%arguments
              msg += exceptions.text_error_template().render()
              print(msg, file=sys.stderr)
              raise
      
      导入系统 从mako导入异常,模板 从mako.template导入defmplate 从mako.runtime导入\u渲染 尝试: template.render(**参数)) 除: #尝试使用适当的文件模板重新创建错误 #这将给出更清晰的错误信息。 将open('failed_template.py','w')作为out: 输出。写入(模板。\u代码) 导入失败\u模板 data=dict(callable=failed\u template.render\u body,**参数) 尝试: _渲染(DefTemplate(模板,失败的模板。渲染体), 失败的\u模板。渲染\u正文, [], (数据) 除: msg='\n'%1!' msg+=异常。文本\错误\模板() 打印(消息,文件=sys.stderr) 提升
我发现Mako存在这个普遍问题。也许你应该试试金甲2,因为它是1。回溯进入模板代码,2。通过沙箱,视图和模型有了更好的分离。我真的不喜欢Jinja的块(类似于Mako的def),因为它们在被调用/和/定义的地方得到了响应。Mako将它们分离——它们只在被称为的地方得到回声。也就是说,我对Mako感到非常失望,所以我很快就会尝试Jinja。谢谢。也许还值得考虑将更复杂的逻辑从模板层移到应用程序的其他层中。@Nikhil:Jinja2也与Mako的defs相当。它们被称为宏:。@Prairie Dogg:也许只是对Mako语法缺乏经验,因为我没有将逻辑编码到模板中@nosklo:太好了。谢谢还有一个用于非HTML环境的.render()。嗯,最好避免捕获所有例外。有人能告诉我如何使用这段代码吗?我是说什么是乌里?在我的python脚本中放置此代码的位置似乎有必要添加第二个答案,以获得合理的错误消息,即
app.config['MAKO_TRANSLATE_EXCEPTIONS']=False
我包装了render_模板函数以包含异常处理,类似这样的内容:
从flask.ext.mako导入render_template作为render_template_1
def render_template(*args,**kwargs):尝试:返回render_template_1(*args,**kwargs2),除了:…
不能作为注释使用,我会将其放在答案中。至于我也在使用的
挂架,不幸的是,
挂架/error.py中处理\u mako_错误
不正确,应以
提升
结束(exc,None,sys.exc_info()[2])
。可以复制该函数并为应用程序修复它。看起来现在您可以通过flask配置选项启用行为:MAKO_TRANSLATE_EXCEPTIONS=FalseVery handy:)我只需要添加一些导入:从MAKO导入sys导入异常,从MAKO导入模板从MAKO导入defmetate.runtime导入_rendergoodone,忘记添加导入。我将编辑答案,谢谢。
import sys
from mako import exceptions, template 
from mako.template import DefTemplate
from mako.runtime import _render

<Do Great Stuff>

try:
    template.render(**arguments))
except:
    # Try to re-create the error using a proper file template
    # This will give a clearer error message.
    with open('failed_template.py', 'w') as out:
        out.write(template._code)
    import failed_template
    data = dict(callable=failed_template.render_body, **arguments)
    try:
        _render(DefTemplate(template, failed_template.render_body),
                failed_template.render_body,
                [],
                data)
    except:
        msg = '<An error occurred when rendering template for %s>\n'%arguments
        msg += exceptions.text_error_template().render()
        print(msg, file=sys.stderr)
        raise