在googleappengin中调试Jinja2

2024-05-13 21:26:53 发布

您现在位置:Python中文网/ 问答频道 /正文

当我在googleappengine中运行Jinja2时,我得到了无用的调试信息。我想这是因为FAQ中的这一项:

My tracebacks look weird. What’s happening?

If the speedups module is not compiled and you are using a Python installation without ctypes (Python 2.4 without ctypes, Jython or Google’s AppEngine) Jinja2 is unable to provide correct debugging information and the traceback may be incomplete. There is currently no good workaround for Jython or the AppEngine as ctypes is unavailable there and it’s not possible to use the speedups extension.

虽然目前还没有“好的”解决办法,但是否有任何解决办法,以便在出现异常时打印的信息更有用?在

谢谢你的阅读。在

布莱恩


Tags: orandthetojinja2isnotjython
3条回答

您可以通过使用monkeypatching将类型和格式塔添加到开发服务器的C模块白名单中来解决这个问题。在

为此,请将以下片段放在主.py公司名称:

import os
if os.environ.get('SERVER_SOFTWARE', '').startswith('Dev'):
    # Enable ctypes for Jinja debugging
    from google.appengine.tools.dev_appserver import HardenedModulesHook
    HardenedModulesHook._WHITE_LIST_C_MODULES += ['_ctypes', 'gestalt']

如果您有类似的仅本地模块需求,也可以使用这个技巧来启用其他C模块。请注意,这些模块在部署之后仍然无法实际工作,因此请小心操作。在

在使用python2.7的sdk1.6.3中,需要将上述代码更改为:

^{pr2}$

在用于python 2.7的SDK 1.8.6上,请尝试以下操作:

PRODUCTION_MODE = not os.environ.get(
    'SERVER_SOFTWARE', 'Development').startswith('Development')
if not PRODUCTION_MODE:
    from google.appengine.tools.devappserver2.python import sandbox
    sandbox._WHITE_LIST_C_MODULES += ['_ctypes', 'gestalt']

我使用以下monkeypatch在Jinja2模板渲染期间发生异常时启用稍微有用的信息:

# Enabling this monkeypatch can help track down hard to find errors that crop
# up during template rendering (since Jinja's own error reporting is so
# unhelpful on AppEngine).
real_handle_exception = environment.handle_exception
def handle_exception(self, *args, **kwargs):
    import logging, traceback
    logging.error('Template exception:\n%s', traceback.format_exc())
    real_handle_exception(self, *args, **kwargs)
environment.handle_exception = handle_exception

这将使错误日志中的异常回溯更加精确。我不认为它通常不会准确地显示出什么地方出了问题(但如果我没记错的话,它有时确实会),但它至少会将异常缩小到正确的模板。在

我不知道(或者不记得)为什么会这样。在

作为一个例子,我刚刚添加了一些代码,这些代码将触发我的一个模板的异常。在开发服务器下,“正常”异常处理程序显示如下:

^{pr2}$

但异常不在accounts/base.html模板中,而是在accounts/edit_card.html中。这是在appengine上调试Jinja2模板异常时最令人沮丧的部分:异常的来源几乎总是被误传。根据我的经验,源代码通常被报告为父模板或某个模板宏。在

安装了异常日志monkeypatch后,相同的异常会在日志中生成此回溯:

Traceback (most recent call last):
  File "/Users/will/workspace/keypremium/ki/ext/jinja2/environment.py", line 702, in render
    return concat(self.root_render_func(self.new_context(vars)))
  File "/Users/will/workspace/keypremium/templates/accounts/edit_card.html", line 11, in root
    <div class="errors">
  File "/Users/will/workspace/keypremium/templates/accounts/base.html", line 11, in root
    </html>
  File "/Users/will/workspace/keypremium/templates/accounts/edit_card.html", line 54, in block_content
    <td>{{ form.cvv2|safe }}</td>
  File "/Users/will/workspace/keypremium/ki/ext/jinja2/environment.py", line 352, in getattr
    return getattr(obj, attribute)
  File "/Users/will/workspace/keypremium/ki/ext/jinja2/runtime.py", line 445, in _fail_with_undefined_error
    raise self._undefined_exception(hint)
UndefinedError: 'sequence' is undefined

这里还有很多无关的信息,但这次回溯至少给我指明了正确的方向。它声称问题出现在accounts/edit_card.html(正确的模板)的第54行,但实际的异常发生在第86行。在

但是如果有正确的模板和正确的异常,我可以很容易地发现麻烦的代码是

{% for x in sequence.sequence() %}
    {{ x.y }}
{% endfor %}

其中模板上下文中没有sequence变量。在

这不是一个完美的解决方案,但我发现它非常有用。在

也许只需使用PyCharm的交互式调试器并逐步完成代码:

http://www.jetbrains.com/pycharm/quickstart/#RunAndDebug

相关问题 更多 >