diff --git a/changelogs/fragments/65365-fix-tb-printing-hostvars.yml b/changelogs/fragments/65365-fix-tb-printing-hostvars.yml new file mode 100644 index 00000000000..dcf753c7914 --- /dev/null +++ b/changelogs/fragments/65365-fix-tb-printing-hostvars.yml @@ -0,0 +1,2 @@ +bugfixes: + - Fix traceback when printing ``HostVars`` on native Jinja2 (https://github.com/ansible/ansible/issues/65365) diff --git a/lib/ansible/vars/hostvars.py b/lib/ansible/vars/hostvars.py index 3159b920ce0..b47ec1975ce 100644 --- a/lib/ansible/vars/hostvars.py +++ b/lib/ansible/vars/hostvars.py @@ -49,7 +49,6 @@ class HostVars(Mapping): ''' A special view of vars_cache that adds values from the inventory when needed. ''' def __init__(self, inventory, variable_manager, loader): - self._lookup = dict() self._inventory = inventory self._loader = loader self._variable_manager = variable_manager @@ -77,6 +76,19 @@ class HostVars(Mapping): return self._variable_manager.get_vars(host=host, include_hostvars=False) + def __setstate__(self, state): + self.__dict__.update(state) + + # Methods __getstate__ and __setstate__ of VariableManager do not + # preserve _loader and _hostvars attributes to improve pickle + # performance and memory utilization. Since HostVars holds values + # of those attributes already, assign them if needed. + if self._variable_manager._loader is None: + self._variable_manager._loader = self._loader + + if self._variable_manager._hostvars is None: + self._variable_manager._hostvars = self + def __getitem__(self, host_name): data = self.raw_get(host_name) if isinstance(data, AnsibleUndefined): diff --git a/lib/ansible/vars/manager.py b/lib/ansible/vars/manager.py index 117f3fb6bc1..e3398a90ce3 100644 --- a/lib/ansible/vars/manager.py +++ b/lib/ansible/vars/manager.py @@ -133,6 +133,8 @@ class VariableManager: self._inventory = data.get('inventory', None) self._options_vars = data.get('options_vars', dict()) self.safe_basedir = data.get('safe_basedir', False) + self._loader = None + self._hostvars = None @property def extra_vars(self): diff --git a/test/integration/targets/jinja2_native_types/inventory.jinja2_native_types b/test/integration/targets/jinja2_native_types/inventory.jinja2_native_types index e69de29bb2d..c1ed0a24cfe 100644 --- a/test/integration/targets/jinja2_native_types/inventory.jinja2_native_types +++ b/test/integration/targets/jinja2_native_types/inventory.jinja2_native_types @@ -0,0 +1 @@ +host1 diff --git a/test/integration/targets/jinja2_native_types/runme.sh b/test/integration/targets/jinja2_native_types/runme.sh index bd05bd5f1fa..0326780b4b3 100755 --- a/test/integration/targets/jinja2_native_types/runme.sh +++ b/test/integration/targets/jinja2_native_types/runme.sh @@ -4,3 +4,4 @@ set -eux ANSIBLE_JINJA2_NATIVE=1 ansible-playbook -i inventory.jinja2_native_types runtests.yml -v "$@" ANSIBLE_JINJA2_NATIVE=1 ansible-playbook -i inventory.jinja2_native_types --vault-password-file test_vault_pass test_vault.yml -v "$@" +ANSIBLE_JINJA2_NATIVE=1 ansible-playbook -i inventory.jinja2_native_types test_hostvars.yml -v "$@" diff --git a/test/integration/targets/jinja2_native_types/test_hostvars.yml b/test/integration/targets/jinja2_native_types/test_hostvars.yml new file mode 100644 index 00000000000..31f5ec9d3ac --- /dev/null +++ b/test/integration/targets/jinja2_native_types/test_hostvars.yml @@ -0,0 +1,10 @@ +- hosts: host1 + gather_facts: no + tasks: + - name: Print vars + debug: + var: vars + + - name: Print hostvars + debug: + var: hostvars