我正在开发一个程序,从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
的适当方法是什么?
谢谢!
答案 0 :(得分:0)
我查看了源代码,从2.11.2版本开始这是不可能的。
构建代码的AST时,iframe
被解析为Custom(1)
节点,它是jinja2.nodes.Call
的子类。
jinja2.nodes.Expr
方法未实现,它仅引发一个异常(Expr.as_const
)。