Repository: ansible/ansible

Issue:
Create magic variable that contains the value of sys.executable
##### ISSUE TYPE
 - Feature Idea

##### COMPONENT NAME
Playbook variables

##### ANSIBLE VERSION
N/A

##### CONFIGURATION
N/A

##### OS / ENVIRONMENT
N/A

##### SUMMARY
As discussed in `#ansible-devel`, it would be useful to have a magic global variable named something like `ansible_playbook_interpreter` that contains the value of `sys.executable`. This allows explicit use of the python interpreter used to run `ansible-playbook` rather than relying on the current implicit behavior that is triggered when you don't include `localhost` in your inventory.

Use in the inventory:

```
localhost2 ansible_connection=localhost ansible_python_interpreter="{{ansible_playbook_interpreter}}"
```

Use in a playbook:

```
- hosts: somegroup
  connection: local
  vars:
    ansible_python_interpreter: "{{ ansible_playbook_interpreter }}"
```

##### STEPS TO REPRODUCE
N/A

##### EXPECTED RESULTS
N/A

##### ACTUAL RESULTS
N/A


Discussion:
@bcoca 

Hi, I've worked on magic vars before, happy to work on this 


Resolving patch:
diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py
--- a/lib/ansible/plugins/action/__init__.py
+++ b/lib/ansible/plugins/action/__init__.py
@@ -694,7 +694,7 @@ def _parse_returned_data(self, res):
                         pass
 
                 # remove some KNOWN keys
-                for hard in ['ansible_rsync_path']:
+                for hard in ['ansible_rsync_path', 'ansible_playbook_python']:
                     if hard in fact_keys:
                         remove_keys.add(hard)
 
diff --git a/lib/ansible/vars/__init__.py b/lib/ansible/vars/__init__.py
--- a/lib/ansible/vars/__init__.py
+++ b/lib/ansible/vars/__init__.py
@@ -20,6 +20,7 @@
 __metaclass__ = type
 
 import os
+import sys
 
 from collections import defaultdict, MutableMapping
 
@@ -392,6 +393,7 @@ def _get_magic_variables(self, loader, play, host, task, include_hostvars, inclu
 
         variables = dict()
         variables['playbook_dir'] = loader.get_basedir()
+        variables['ansible_playbook_python'] = sys.executable
 
         if host:
             variables['group_names'] = sorted([group.name for group in host.get_groups() if group.name != 'all'])


Test patch:
diff --git a/test/units/vars/test_variable_manager.py b/test/units/vars/test_variable_manager.py
--- a/test/units/vars/test_variable_manager.py
+++ b/test/units/vars/test_variable_manager.py
@@ -47,14 +47,11 @@ def test_basic_manager(self):
 
         v = VariableManager()
         vars = v.get_vars(loader=fake_loader, use_cache=False)
-        if 'omit' in vars:
-            del vars['omit']
-        if 'vars' in vars:
-            del vars['vars']
-        if 'ansible_version' in vars:
-            del vars['ansible_version']
-        if 'ansible_check_mode' in vars:
-            del vars['ansible_check_mode']
+
+        #FIXME: not sure why we remove all and only test playbook_dir
+        for remove in ['omit', 'vars', 'ansible_version', 'ansible_check_mode', 'ansible_playbook_python']:
+            if remove in vars:
+                del vars[remove]
 
         self.assertEqual(vars, dict(playbook_dir='.'))