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 warning if playbook references a var that shadows a builtin method #22273
Conversation
CI failure in integration tests due to:
Also, the test
|
The warning seems like a good idea as the original error is a bit cryptic but changing the behaviour has the potential to break things. here's a bit of a contrived example:
Ah, here's a more useful example:
|
reference a objects method attrs result in getting the repr of the method in devel/.
|
No, it results in getting the method. you see the repr when you attempt to print the method. but most of the time you want to use the method, not print it. We can't tell in the getattr how the method is going to be used. My example of '{{ mydict.keys() }}' is a perfectly valid thing to want to do and with your patch that would be broken. bcoca also raises the question of performance. We template quite a lot and the templating is already slow. Intercepting getattr would slow that further. We'd want to benchmark the overhead of adding the warning when there's many variables before we push just the warning code in. |
Display a warning if a template references a attribute name that is a object method and also an item in the data. In this ambiquous scenario, dislay the warning, then return the object method and not the data item.
bot_status |
The test
|
waiting_on: alikins |
closing this as we documented the behaviour and the cost of detection becomes prohibitive at runtime. |
ISSUE TYPE
COMPONENT NAME
lib/ansible/template/init.py
ANSIBLE VERSION
SUMMARY
There is a silent gotcha lurking in http://docs.ansible.com/ansible/playbooks_variables.html#what-makes-a-valid-variable-name
If playbook yaml data structures contain fields with any ~80 var names listed there, and the playbook references them via dot/getattr access ( "{{ my_data.my_field }}"), instead of returning the data item set in the data structure, a reference to the python builtin methods of the same names will be returned.
There is a way to avoid that (using {{ my_data['my_field'] }} to prefer the getitem()), but it is very easy to accidentally use a shadowed builtin and the getattr/dot access method and end up with a the method reference which caused very confusing error messages and other weird failures.
ie, if my_data:
If playbook uses '{{ my_data.get }}', the result will be something like '<built-in method get of dict object at 0x7fdef81cc050>' instead of 'http://www.ansible.com'
This pr adds a warning message for that case. It also changes the behavior to prefer the data item ('http://www.ansible.com') for cases where data items shadow built in methods. A reference to
'{{ my_data.popitem }}' will still return the method reference (popitem is not shadowed).
The patch detects if a getattr is used on the object could also reference a data item. If so, it warns and returns the data item.