Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to test type #358

Closed
tb123 opened this issue Aug 13, 2014 · 5 comments
Closed

No way to test type #358

tb123 opened this issue Aug 13, 2014 · 5 comments

Comments

@tb123
Copy link

tb123 commented Aug 13, 2014

We need a way to be able to test the type of an object is equal to one another.

An example use case is when trying to print a certain type of form element based on the type of a given object.

@kooky
Copy link
Contributor

kooky commented Aug 20, 2014

Do you really need to know the type? Are the tests like number and string not enough?

http://jinja.pocoo.org/docs/templates/#list-of-builtin-tests

I guess you could add type as a customer filter. But this really doesn't feel very useful.

import jinja2

env=jinja2.Environment()
env.filters['type'] = type

template =env.from_string("""begin {{ note|type }} end""")
print(template.render(note='hello'))
print(template.render(note=1))

output:

begin <type 'str'> end
begin <type 'int'> end

@ThiefMaster
Copy link
Member

That can be easily added by creating a custom test and adding it to your template context. Afterwards you could e.g. use {% if foo is type Bar %} (maybe an instanceof test would make more sense).

However, I'd say it's much cleaner if you expose the "type" of your object via an attribute. After all, they'll be somehow similar, maybe even of a common base class? Based on your form field example, {% if field.type == 'password' %} would be better than {% if field is instanceof PasswordField %} - the latter would be much closer to code (which is something you want to avoid in a template) and also require you to expose the actual class PasswordField to your template.

@k0ste
Copy link

k0ste commented Jun 7, 2016

Come here from google.

Case: if 1 (one) address, then make string, else make array.

string_address: '10.10.10.10/24'
list_adress:
  - 10.10.10.10/24
  - 10.10.20.20/24
{% if item.address is defined and item.address | ipaddr('host/prefix') %}
{% if item.address is string %}
Address=('{{ item.address }}')
{% elif item.address %}
Address=({% if item.address %}{{ '\'' + item.address | join('\' \'') + '\'' }}{% endif %})
{% endif %}
{% endif %}

With jinja we can check type is string. It could be someone will be useful.

@davidism davidism closed this as completed Jun 7, 2016
@k0ste
Copy link

k0ste commented Jul 13, 2017

One year later...

Check for the data type can be made even more accurate (for example string or sequence).

---
network_scripts_interfaces:
- interface: 'vlan2'
  address:
  - '192.168.1.1/24'
  - '192.168.2.1/24'
- interface: 'vlan3'
  address: '192.168.3.1/24'
{% if item.address is defined and item.address != '' %}
{% if item.address is string and item.address | ipaddr('host/prefix') %}
{{ 'IPADDR' + '=\"' + item.address + '\"' }}
{% elif item.address is sequence %}
{% for addr in item.address %}
{% if addr | ipaddr('host/prefix') %}
{{ 'IPADDR' ~ loop.index ~ '=\"' ~ addr ~ '\"' }}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}

@artheus
Copy link

artheus commented Nov 20, 2018

One year later...

Check for the data type can be made even more accurate (for example string or sequence).

---
network_scripts_interfaces:
- interface: 'vlan2'
  address:
  - '192.168.1.1/24'
  - '192.168.2.1/24'
- interface: 'vlan3'
  address: '192.168.3.1/24'
{% if item.address is defined and item.address != '' %}
{% if item.address is string and item.address | ipaddr('host/prefix') %}
{{ 'IPADDR' + '=\"' + item.address + '\"' }}
{% elif item.address is sequence %}
{% for addr in item.address %}
{% if addr | ipaddr('host/prefix') %}
{{ 'IPADDR' ~ loop.index ~ '=\"' ~ addr ~ '\"' }}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}

This is might not work as expected, as string type will also be true if you test with is sequence

is sequence does only test if the variable is iterable. Which means that array, string and dict will all test True with is sequence.
So the only way to test for a list, right now. Is using something like this:

{% if item.address is sequence and item.address is not string and item.address is not mapping %}
-- item.address should be a list in here --
{% endif %}

Therefore it would be really great to add strict type comparisons. So we could do item.address is dict, item.address is array and item.address is string. Where only the last one is available, right now.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants