从Jinja模板中提取变量

时间:2020-06-24 01:00:43

标签: python jinja2

我正在开发一个程序,从jinja模板中提取变量。

到目前为止,它工作正常:

from jinja2 import Environment
from jinja2.nodes import Assign

template = "{% set x = 1%}"
env = Environment()
ast = env.parse(template)

assert {n.target.name: n.node.as_const() for n in ast.find_all(Assign)} == {'x': 1}

但是用户可能会使用具有某些格式逻辑的自定义类,因此我尝试将Custom传递给env.globals,如下所示:

from jinja2 import Environment
from jinja2.nodes import Assign

class Custom:
    def __init__(self, value):
        return self.value

    def __str__(self):
        return str(self.value)

template = "{% set x = Custom(1) %}"
env = Environment()
env.globals['Custom'] = Custom
ast = env.parse(template)

{n.target.name: n.node.as_const() for n in ast.find_all(Assign)} 
# I'd like this to be: {'x': Custom(1)}

但是我得到这个错误:

~/miniconda3/envs/ploomber/lib/python3.6/site-packages/jinja2/nodes.py in as_const(self, eval_ctx)
    416            the `eval_ctx` parameter was added.
    417         """
--> 418         raise Impossible()
    419
    420     def can_assign(self):

Impossible:

我还尝试在Custom函数中将eval_ctx传递给as_const(),但是遇到相同的错误。

Environment意识到Custom的适当方法是什么?

谢谢!

  • Python版本:3.6.10
  • Jinja版本:2.11.2

1 个答案:

答案 0 :(得分:0)

我查看了源代码,从2.11.2版本开始这是不可能的。

构建代码的AST时,iframe被解析为Custom(1)节点,它是jinja2.nodes.Call的子类。

jinja2.nodes.Expr方法未实现,它仅引发一个异常(Expr.as_const)。