Jinja2 syntax for conditionals (was: Re: Project options and other format enhancements (and dropping "variants"))



On 18/09/17 12:35, Sam Thursfield wrote:
What I'm suggesting is that we avoid creating a new DSL for expressions in the first place, we try and reuse an existing one instead. Ansible's use of Jinja proves that this is possible. I'm not entirely sure how it works though -- if I get time I will try and make a proof of concept expression parser and we can see if it can beat your 218 lines of code :-)

Attached is a proof of concept that demonstrates what I'm talking about. Also pasted here: https://pastebin.com/hmk0TPQj

It allows expressions that follow the Jinja2 expression syntax, as documented at: http://jinja.pocoo.org/docs/2.9/templates/#expressions

This supports arithmetic expressions (with infix syntax :-), compound conditionals like 'foo or (bar and baz)', string comparisons (case sensitive), list handling such as 'if "feature" in feature_list', all with a very Python-like syntax.

Some examples:

  9 + 5 == 14    (evaluates to True)
  "foo" in ["foo", "bar", "baz"]   (evaluates to True)

You can pass a dict of key->values into the evaluation function which become usable as variables within the condition expression. Booleans, integers, strings and lists are supported (and possibly more). For example if we pass "myvariable" set to the string "foo", we can use it like this:

  myvariable   (evaluates to True)
  myvariable == "boris"   (evaluates to False)
  myvariable[0] == "f"    (evaluates to True)

etc.

The whole thing is only 150 lines, and could be less if we didn't care about the "is defined" / "is undefined" operators (which require some special case hackery).

To make it work we just embed the condition expression into a template and then render it through jinja2 to get a result. Of course it feels a bit dirty, but Ansible has been doing this since 2012 to implement 'when' conditions in playbooks and it seems to be working well enough for their tens of thousands of users.

Sam


--
Sam Thursfield, Codethink Ltd.
Office telephone: +44 161 236 5575

Attachment: jinja-expressions-test.py
Description: Text Data



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]