-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add more strict type tests #824
Conversation
f0ee501
to
ba18cdb
Compare
list is not a good name as it is not detecting whether the data type is a python list. What's really meant is |
Related to Issue #358 |
What about |
|
All of this seems very specific to Ansible. I've never had to do these sorts of type checks in templates, or in most Python code in general. Maybe the issue with inconsistent data that users have to check is something that needs to be addressed by Ansible? |
For the boolean, why can't For "sequence not string", you can already do this with
For int vs float as opposed to "number", why does it matter at the template level what type these are? If you absolutely need one or the other, then use |
Why not to add |
Testing against strings sounds really error-prone. |
From the one side 'yes'. From the other... According this discussion current set of type testers can't guarantee the strong types distinguishing from each other. Another point: this feature will allow to authors decribe theirs own types came outside of template engine. Personally I have faced with the problem: I reflect variant type into Jinja template but haven't got the "standard" way to describe the currently reflected particular type from the variant cases. |
If you really want to test based on strings, you can already do that with This whole thing seems like something that should not have to be done in templates, but the problem is that there are already some type tests so it's not clear what was intended and if it's ok to keep piling more in. |
Yes. You right. It's better to implement via extension/application-specific test. |
Well, since we need this as part of generating documentation, I don't think this really is an Ansible-specific issue. And I have proposed this for Ansible specifically, but IMO proper type-checking for all types is something the language could help with. I understand that if you are using Jinja for web-based templating and you have control over the data, this may be less of an issue, but Jinja is not (no longer) used as a one-purpose template engine. And yes, we are using constructions like @davidism So despite the naming of non-string sequences, you object to everything else too ? Testing for booleans is a dangerous thing too if there's no 'boolean' test. Without some of these tests Jinja is a minefield to most non-experts. |
Some real-life advice on forums:
If you don't think there's a problem in Jinja (beyond your use-cases), StackOverflow is a good reality check IMO. And I had some of the same issues before I decided we could do better and created the PR in Ansible and upstreamed it here. |
ba18cdb
to
a442d4d
Compare
I'm not saying your use case isn't important, I'm trying to understand where this belongs and why users are trying to do these things in the first place. And if we add these, why not every type in builtins and every abc in collections? And what about user-provided types? Maybe there's a better solution to checking types instead of adding individual tests for each? |
I suppose, arithmetic operations on ints and floats will have different results. Formatting of big numbers as well.
May be extra 'universal' tester could help? Something like: |
In our case the documentation is generated from contributed YAML files, so we do want to ensure that we handle user-contributed input correctly and produce correct output regardless of the input type. Here is one of the use-cases where we added the list-test ourselves: https://github.com/ansible/ansible/pull/37514/files So we have cases where the data provided could be a string or a list, and depending on which we also have to check if a value is the same as the string, or is included in the lists. |
I'm still interested in exploring the last question I asked:
If we merge this as-is, rather than exploring that, we still need to decide on a name for the We should also consider @abadger's point about whether we want to test |
If we would go to a hand-off type of test, I'd rather have a 'type' test in the same light as 'sameas', rather than having switches to existing tests. ( {% if variable is type boolean %}
{% if variable is type integer %}
{% if variable is type float %}
{% if variable is type string %}
{% if variable is type list %}
{% if variable is type mapping %} Should we be testing for python types, or rather switch to Jinja naming above ? |
This comment has been minimized.
This comment has been minimized.
Can someone make a (design) decision on this topic? |
I'm fine with it except for the |
I will remove the |
Please review! |
I mean, I think such a test makes sense, I just want a good name. It's not hijacking the PR, since I'm not planning to merge it right this moment anyway. But we can leave it for another time, that's fine too. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a changelog entry as well.
c9996c3
to
17a9cf4
Compare
I updated the tests, add a changelog entry and updated the docs. |
This PR adds a few more type-related tests. - boolean Testing of an object is a boolean required 2 tests. - false Make this similar to testing none value - true Make this similar to testing none value - integer The existing 'number' test does not make a distinction between integer, float or even booleans - float The existing 'number' test does not make a distinction between integer, float or even booleans
1945f22
to
9bd3cb2
Compare
Thanks for working on this, it's marked for 2.11. |
This PR adds a few more type-related tests.
boolean
Testing if an object is a boolean required 2 tests.
false
Make this similar to testing none value, not requiring sameas
true
Make this similar to testing none value, not requiring sameas
integer
The existing 'number' test does not make a distinction between
integer, float or even booleans
float
The existing 'number' test does not make a distinction between
integer, float or even booleans
listThe existing 'sequence' or 'iterable test does not make a distinctionbetween strings, lists or mappings. Even 'iterable' does not help here.
This brings the same convenience as:
none
string
mapping
For the original Jinja2 use-case where values eventually turn into strings anyway, type-checking is less of an issue, however in Ansible or other projects that use Jinja2 for more than web-templating this is more important.
We see people turning booleans into strings to compare with 'True' or 'False'. Or doing very weird things to determine what is a string, or a list. If you're not careful you end up with a character, instead of the first element.
You can see the effect of testing different types in Jinja including these new tests:
https://github.com/dagwieers/ansible/blob/jinja2-type-tests/test/integration/targets/jinja2_tests/tasks/main.yml
PS This PR also has a workaround for a small doc issue breaking Travis testing.