'Can I pass non-string types via environment variables to meta.yaml?

I am aware that conda's meta.yaml file uses jinja templating, which allows us to pass values to it via environment variables. For example like this:

package:
  name: {{ MY_PKG_NAME }}
  version: {{ MY_PKG_VERSION }}

When running conda render with those environment variables, I would get the following output yaml.

$ MY_PKG_NAME=foo MY_PKG_VERSION=1.2.3 conda render .
package:
  name: foo
  version: 1.2.3

So far so good. Now, I was wondering if I could pass other objects such as lists or dicts via environment variables. For example to achieve something like this:

build:
  entry_points:
    {% for ep in environ["ENTRY_PTS"] %}
    - {{ ep["name"] }} = {{ ep["cmd"] }}
    {% endfor %}

Then rendering with an environment variable like this should produce the following output:

$ ENTRY_PTS='[{"name": "foo", "cmd": "foo:main"}, {"name": "bar", "cmd": "bar:main"}]' conda render .
build:
  entry_points:
    - foo = foo:main
    - bar = bar:main

The above is obviously a naive approach as environ["ENTRY_PTS"] would just be a string, but I tried things like this:

{% for ep in json.loads(environ["ENTRY_PTS"]) %}
{% for ep in ast.literal_eval(environ["ENTRY_PTS"]) %}
{% for ep in eval(environ["ENTRY_PTS"]) %}

None of these worked, but my question is, is there any way to parse even slightly more complex types from environment variables?



Solution 1:[1]

I have created this merge request to conda-build which would support this.

The proposed functionality would look like this for my example:

build:
  entry_points:
    {% for ep in load_str_data(environ["ENTRY_PTS"], "json") %}
    - {{ ep["name"] }} = {{ ep["cmd"] }}
    {% endfor %}

https://github.com/conda/conda-build/pull/4465

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Abraham Murciano Benzadon