# \`ansible-playbook\` (\`ansible-core 2.17.1\`) fails on target with \`python 3.9\`

**URL:** <https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700>\
**Category:** Get Help\
**Tags:** python, ansible-core\
**Created:** [June 21, 2024, 7:44am UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700 "2024-06-21T07:44:25Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![sfleisch](https://avatars.discourse-cdn.com/v4/letter/s/ed8c4c/32.png) [@sfleisch](https://forum.ansible.com/u/sfleisch)\
**Post date:** [June 21, 2024, 7:44am UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/1 "2024-06-21T07:44:25Z")

</div>

Hi all,

I have an Ansible target machine running Rocky Linux 8 with Python 3.9.19 installed.

```bash
[ansible@punch2 ~]$ python3 --version
Python 3.9.19
[ansible@punch2 ~]$ which python3
/usr/bin/python3
[ansible@punch2 ~]$ file $(which python3)
/usr/bin/python3: symbolic link to /etc/alternatives/python3
[ansible@punch2 ~]$ file /etc/alternatives/python3
/etc/alternatives/python3: symbolic link to /usr/bin/python3.9

```

On my control node I have `ansible-core 2.17.1` and `python 3.12.4`  
According to the `ansible-core` support matrix [1] this should be a working combination.

However, running my playbook fails with

```auto
TASK [install rsync] *********************************************************************************************************************
fatal: [punch2]: FAILED! => {"changed": false, "module_stderr": "Shared connection to punch2 closed.\r\n", "module_stdout": "\r\nTraceback (most recent call last):\r\n File \"<stdin>\", line 12, in <module>\r\n File \"<frozen importlib._bootstrap>\", line 971, in _find_and_load\r\n File \"<frozen importlib._bootstrap>\", line 951, in _find_and_load_unlocked\r\n File \"<frozen importlib._bootstrap>\", line 894, in _find_spec\r\n File \"<frozen importlib._bootstrap_external>\", line 1157, in find_spec\r\n File \"<frozen importlib._bootstrap_external>\", line 1131, in _get_spec\r\n File \"<frozen importlib._bootstrap_external>\", line 1112, in _legacy_get_spec\r\n File \"<frozen importlib._bootstrap>\", line 441, in spec_from_loader\r\n File \"<frozen importlib._bootstrap_external>\", line 544, in spec_from_file_location\r\n File \"/tmp/ansible_ansible.legacy.dnf_payload_7b004s9t/ansible_ansible.legacy.dnf_payload.zip/ansible/module_utils/basic.py\", line 5\r\nSyntaxError: future feature annotations is not defined\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

```

The affected task is:

```auto
    - name: "install rsync"
      ansible.builtin.dnf:
        name: "rsync"
        state: "present"

```

I thought perhaps ansible uses an incorrect python executable on the target host, but it looks like it uses the correct one:

```auto
$ grep -i python /tmp/ansible.log 
            "SUDO_COMMAND": "/bin/sh -c echo BECOME-SUCCESS-zjjlkkwbuieqcjgtuknfnroqnampysct ; /usr/bin/python3.9 /home/ansible/.ansible/tmp/ansible-tmp-1718955443.6279042-120117-145070664808475/AnsiballZ_setup.py",
            "_": "/usr/bin/python3.9"
            "discovered_interpreter_python": "/usr/bin/python3.9",
                "SUDO_COMMAND": "/bin/sh -c echo BECOME-SUCCESS-zjjlkkwbuieqcjgtuknfnroqnampysct ; /usr/bin/python3.9 /home/ansible/.ansible/tmp/ansible-tmp-1718955443.6279042-120117-145070664808475/AnsiballZ_setup.py",
                "_": "/usr/bin/python3.9"
            "python": {
                "executable": "/usr/bin/python3.9",
                "type": "cpython",
            "python_version": "3.9.19",
            "selinux_python_present": true,
        "ansible_playbook_python": "/usr/bin/python",
        "ansible_python": {
            "executable": "/usr/bin/python3.9",
            "type": "cpython",
        "ansible_python_version": "3.9.19",
        "ansible_selinux_python_present": true,
        "discovered_interpreter_python": "/usr/bin/python3.9",

```

Is this the expected behaviour?

When I downgrade `ansible-core` on my control node to `2.16.6`, the playbook runs normally.

[1] [Releases and maintenance — Ansible Community Documentation](https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix)

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [June 21, 2024, 10:22am UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/2 "2024-06-21T10:22:10Z")

</div>

You could run the playbook with `-vvv` to get more info, also which interpreter is actually used for that task.

---

<div class="post-metadata">

**Author:** ![sfleisch](https://avatars.discourse-cdn.com/v4/letter/s/ed8c4c/32.png) [@sfleisch](https://forum.ansible.com/u/sfleisch)\
**Post date:** [June 21, 2024, 10:47am UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/3 "2024-06-21T10:47:38Z")

</div>

Control node:

```bash
$ ansible-playbook -vvv -i inventory -K punch2/punch2.yml --diff > /tmp/ansiblevvv.log

$ grep -i python /tmp/ansiblevvv.log
  ansible python module location = /usr/lib/python3.12/site-packages/ansible
  python version = 3.12.4 (main, Jun 7 2024, 06:33:07) [GCC 14.1.1 20240522] (/usr/bin/python)
<punch2> Attempting python interpreter discovery
<punch2> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ansible"' -o ConnectTimeout=10 -o 'ControlPath="[...]"' punch2 '/bin/sh -c '"'"'echo PLATFORM; uname; echo FOUND; command -v '"'"'"'"'"'"'"'"'python3.12'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.11'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.10'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.9'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.8'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/bin/python3'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3'"'"'"'"'"'"'"'"'; echo ENDFOUND && sleep 0'"'"''
<punch2> (0, b'PLATFORM\nLinux\nFOUND\n/usr/bin/python3.9\n/usr/bin/python3\n/usr/bin/python3\nENDFOUND\n', b"OpenSSH_9.7p1, OpenSSL 3.3.1 4 Jun 2024\r\ndebug1: Reading configuration data
[...]
 "ansible_selinux_python_present": true, "ansible_selinux": {"status": "enabled", "policyvers": 33, "config_mode": "permissive", "mode": "permissive", "type": "targeted"}, "ansible_env": {"LS_COLORS": "rs=0:di=38;5;33:ln=38;5;51:mh=00:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=01;05;37;41:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;40:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.zst=38;5;9:*.tzst=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.wim=38;5;9:*.swm=38;5;9:*.dwm=38;5;9:*.esd=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.mjpg=38;5;13:*.mjpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.m4a=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.oga=38;5;45:*.opus=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:", "LANG": "en_US.UTF-8", "SUDO_GID": "1000", "SUDO_COMMAND": "/bin/sh -c echo BECOME-SUCCESS-javmnmtzucrhyqcgcyucxbreqcmqcogf ; /usr/bin/python3.9 /home/ansible/.ansible/tmp/ansible-tmp-1718966149.599945-164060-177038502487216/AnsiballZ_setup.py", "USER": "root", "PWD": "/home/ansible", "HOME": "/root", "SUDO_USER": "ansible", "SUDO_UID": "1000", "MAIL": "/var/mail/root", "SHELL": "/bin/bash", "TERM": "xterm-256color", "SHLVL": "1", "LOGNAME": "root", "PATH": "/sbin:/bin:/usr/sbin:/usr/bin", "_": "/usr/bin/python3.9"}, "ansible_iscsi_iqn": "", "ansible_dns": {"search": ["gsi.de"], "nameservers": ["140.181.96.11", "140.181.96.29"]}, "ansible_local": {}, "ansible_hostnqn": "nqn.2014-08.org.nvmexpress:uuid:00000000-0000-0000-0000-000000000000", "ansible_python": {"version": {"major": 3, "minor": 9, "micro": 19, "releaselevel": "final", "serial": 0}, "version_info": [3, 9, 19, "final", 0], "executable": "/usr/bin/python3.9", "has_sslcontext": true, "type": "cpython"}, 
[...]
Using module file /usr/lib/python3.12/site-packages/ansible/modules/dnf.py
<punch2> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ansible"' -o ConnectTimeout=10 -o 'ControlPath="[...]"' -tt punch2 '/bin/sh -c '"'"'sudo -H -S -p "[sudo via ansible, key=tabodqpozselrbxwgvbgexkvfbcgajss] password:" -u root /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-tabodqpozselrbxwgvbgexkvfbcgajss ; /usr/bin/python3.9 /home/ansible/.ansible/tmp/ansible-tmp-1718966151.9287078-164118-26674811716498/AnsiballZ_dnf.py'"'"'"'"'"'"'"'"' && sleep 0'"'"''

```

Trimmed the output a bit.

It appears to me it tries to use `/usr/bin/python3.9`.

---

<div class="post-metadata">

**Author:** ![jborean](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jborean/32/1525_2.png) [@jborean](https://forum.ansible.com/u/jborean)\
**Post date:** [June 21, 2024, 11:44am UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/4 "2024-06-21T11:44:02Z")

</div>

Dnf is a special module that requires the Python dnf bindings to work. It uses a concept called module respawn that will respawn as the Python interpreter that the bindings it requires is installed on. Unfortunately for EL8 based hosts that will be an older Python version which is not compatible with Ansible 2.17. There’s unfortunately not much you can do about modules like this as they require those Python bindings and those bindings are only available on a limited set of Python versions.

---

<div class="post-metadata">

**Author:** ![sfleisch](https://avatars.discourse-cdn.com/v4/letter/s/ed8c4c/32.png) [@sfleisch](https://forum.ansible.com/u/sfleisch)\
**Post date:** [June 21, 2024, 12:22pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/5 "2024-06-21T12:22:02Z")

</div>

In that case I would argue that the documentation at [1] is incorrect, since it suggests any Python version between 3.7 and 3.12 on the target is sufficient.

Also I would argue that the decision to require a relatively new Python version for a task as trivial as calling an executable (in this case `dnf`) and parsing its output to be inappropriate.  
Implementing this using Python bindings may be a bit more luxurious for the programmer of the ansible module, but at the vast expense of everyone who needs ansible to work on EL8 targets.

---

<div class="post-metadata">

**Author:** ![tkshiva252](https://avatars.discourse-cdn.com/v4/letter/t/7ba0ec/32.png) [@tkshiva252](https://forum.ansible.com/u/tkshiva252)\
**Post date:** [July 10, 2024, 8:41pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/6 "2024-07-10T20:41:30Z")

</div>

Even i am facing the same issue after upgrading the ansible version to 2.17 and remote host python version 3.9.\*

may i know how did you downgraded your ansible to 2.16 version? I was not able to find an easy way using brew install

---

<div class="post-metadata">

**Author:** ![sfleisch](https://avatars.discourse-cdn.com/v4/letter/s/ed8c4c/32.png) [@sfleisch](https://forum.ansible.com/u/sfleisch)\
**Post date:** [July 10, 2024, 9:03pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/7 "2024-07-10T21:03:15Z")

</div>

I am unfamiliar with `brew`.  
On Arch, I downgraded `ansible-core` using `$ sudo pacman -U /var/cache/pacman/pkg/ansible-core-2.16.3-1-any.pkg.tar.zst`

---

<div class="post-metadata">

**Author:** ![Thulium-Drake](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/thulium-drake/32/833_2.png) [@Thulium-Drake](https://forum.ansible.com/u/Thulium-Drake)\
**Post date:** [July 11, 2024, 11:49am UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/8 "2024-07-11T11:49:55Z")

</div>

The thing with EL8 platforms is that they do support Python version 3.7 and up. _However_, the issue lies in `/usr/libexec/platform-python`, which is version 3.6.8. There’s been a few blogs about when RHEL8 was released in 2019: [What, no Python in Red Hat Enterprise Linux 8? | Red Hat Developer](https://developers.redhat.com/blog/2019/05/07/what-no-python-in-red-hat-enterprise-linux-8)

The reasoning behind it was, having an OS which _has_ to use the same version of Python as it’s main interpreter for 10+ years is not technically feasable (and comes with a myriad of problems, security and otherwise). Let’s instead decouple the “system” python interpreter from the “userland” interpreter (I use these terms loosely here).

And here’s where Ansible 2.17+ breaks: using “system” modules that require `platform-python` to work. You can run any and all modules on your RHEL8 targets, provided they have a suitable python interpreter, _except_ modules that use “system” python, such as DNF/YUM.

---

<div class="post-metadata">

**Author:** ![sfleisch](https://avatars.discourse-cdn.com/v4/letter/s/ed8c4c/32.png) [@sfleisch](https://forum.ansible.com/u/sfleisch)\
**Post date:** [July 11, 2024, 12:12pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/9 "2024-07-11T12:12:47Z")

</div>

The problem is located in the decision to implement the DNF/YUM ansible modules in the way they are in ansible-core 2.17.

As far as I can tell, and please correct me if I’m wrong here, implementing them through the aforementioned respawn mechanism does not solve any problem. However, it introduces one, quite a considerable one I might add, namely it **breaks** ansible on EL8 targets. (Other targets might be affected too, I haven’t checked)

Therefore, I consider this a reckless decision and request it to be reverted.

The old DNF/YUM module was working reliably and I do not see why it needed to be changed.

---

<div class="post-metadata">

**Author:** ![Thulium-Drake](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/thulium-drake/32/833_2.png) [@Thulium-Drake](https://forum.ansible.com/u/Thulium-Drake)\
**Post date:** [July 11, 2024, 12:34pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/10 "2024-07-11T12:34:18Z")

</div>

I fully agree with you → [Discussion: ansible-core 2.17 removing target support for Python 2.7 and 3.6 · ansible-collections/news-for-maintainers · Discussion #55 · GitHub](https://github.com/ansible-collections/news-for-maintainers/discussions/55)

---

<div class="post-metadata">

**Author:** ![flowerysong](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/flowerysong/32/2305_2.png) [@flowerysong](https://forum.ansible.com/u/flowerysong)\
**Post date:** [July 11, 2024, 6:57pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/11 "2024-07-11T18:57:22Z")

</div>

> [@sfleisch](#):
>
> As far as I can tell, and please correct me if I’m wrong here, implementing them through the aforementioned respawn mechanism does not solve any problem. However, it introduces one, quite a considerable one I might add, namely it **breaks** ansible on EL8 targets. (Other targets might be affected too, I haven’t checked)

You are wrong here. The respawn mechanism has no effect on what targets work, it’s just a convenience that removes the necessity for the user to specify which Python interpreter to use for modules that require the system Python.

Before implementation of respawn: if `ansible_python_interpreter=/usr/local/bin/python3` and the required libraries are only available on `/usr/bin/python3`, the module fails. The user must specify `ansible_python_interpreter=/usr/bin/python3` to get the task to work.

After implementation of respawn: Regardless of what interpreter the module initially runs under, it detects that the required library is available under`/usr/bin/python3` and respawns itself using that interpreter.

In both cases the library requirements are the same and the supported targets are the same. Any modules that do not work under EL8 are because the required libraries are not available for a supported version of Python, not because of the respawn mechanism.

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [July 11, 2024, 7:19pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/12 "2024-07-11T19:19:54Z")

</div>

I created an experiment:

I copied all module\_utils (except C#/PowerShell; and six, since the collection loader will barf if that’s around somewhere outside ansible.builtin…), doc fragments, and the action plugins/modules related to package modules that do respawning (i.e. apt, apt\_repository, dnf, yum) from stable-2.16 to a collection and adjusted the imports, and some more smaller changes (mostly related to how arguments are passed to Python Ansible modules, and new hidden `_ansible_*` parameters added in ansible-core 2.17).

That way, I hope that respawn also works with Python 2.7 and 3.6, since there should be no syntax errors coming from module utils.

Can someone try [GitHub - felixfontein/ansible-py2736compattest](https://github.com/felixfontein/ansible-py2736compattest) (the collection is called felixfontein.py2736compattest) to see whether it works as I hope?

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [July 11, 2024, 7:20pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/13 "2024-07-11T19:20:30Z")

</div>

(This won’t work if you use `package` or `package_facts`, since they have a hard-coded list of package managing modules, or at least they had the last time I checked…)

---

<div class="post-metadata">

**Author:** ![Thulium-Drake](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/thulium-drake/32/833_2.png) [@Thulium-Drake](https://forum.ansible.com/u/Thulium-Drake)\
**Post date:** [July 12, 2024, 4:42pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/14 "2024-07-12T16:42:42Z")

</div>

I’ve run into some issues trying to make it work:

```auto
ansible [core 2.17.1]
  config file = None
  configured module search path = ['/home/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/ansible/.local/share/pipx/venvs/ansible-core-2-17/lib64/python3.12/site-packages/ansible
  ansible collection location = /home/ansible/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/ansible/.local/bin/ansible
  python version = 3.12.3 (main, Apr 17 2024, 00:00:00) [GCC 14.0.1 20240411 (Red Hat 14.0.1-0)] (/home/ansible/.local/share/pipx/venvs/ansible-core-2-17/bin/python)
  jinja version = 3.1.3
  libyaml = True

```

The playbook:

```auto
---
- name: 'Test compat collection for dnf/yum'
  hosts: 'ansible_controller'
  tasks:
    - name: 'Install bash with compat'
      felixfontein.py2736compattest.dnf:
        name: 'bash'
        state: 'present'
    - name: 'Install bash with normal'
      ansible.builtin.dnf:
        name: 'bash'
        state: 'present'

```

The error:

```auto
TASK [Install bash with compat] ******************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: SyntaxError: future feature annotations is not defined
fatal: [m-a05-01.rh.lab]: FAILED! => changed=false 
  module_stderr: |-
    Shared connection to m-a05-01.rh.lab closed.
  module_stdout: |-
    Traceback (most recent call last):
      File "<stdin>", line 12, in <module>
      File "<frozen importlib._bootstrap>", line 971, in _find_and_load
      File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 656, in _load_unlocked
      File "<frozen importlib._bootstrap>", line 626, in _load_backward_compatible
      File "/tmp/ansible_felixfontein.py2736compattest.dnf_payload_0pdp6ito/ansible_felixfontein.py2736compattest.dnf_payload.zip/ansible_collections/felixfontein/py2736compattest/plugins/module_utils/basic.py", line 68, in <module>
      File "<frozen importlib._bootstrap>", line 971, in _find_and_load
      File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 656, in _load_unlocked
      File "<frozen importlib._bootstrap>", line 626, in _load_backward_compatible
      File "/tmp/ansible_felixfontein.py2736compattest.dnf_payload_0pdp6ito/ansible_felixfontein.py2736compattest.dnf_payload.zip/ansible_collections/felixfontein/py2736compattest/plugins/module_utils/compat/selinux.py", line 9, in <module>
      File "<frozen importlib._bootstrap>", line 971, in _find_and_load
      File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 656, in _load_unlocked
      File "<frozen importlib._bootstrap>", line 626, in _load_backward_compatible
      File "/tmp/ansible_felixfontein.py2736compattest.dnf_payload_0pdp6ito/ansible_felixfontein.py2736compattest.dnf_payload.zip/ansible_collections/felixfontein/py2736compattest/plugins/module_utils/common/text/converters.py", line 12, in <module>
      File "<frozen importlib._bootstrap>", line 971, in _find_and_load
      File "<frozen importlib._bootstrap>", line 951, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 894, in _find_spec
      File "<frozen importlib._bootstrap_external>", line 1157, in find_spec
      File "<frozen importlib._bootstrap_external>", line 1131, in _get_spec
      File "<frozen importlib._bootstrap_external>", line 1112, in _legacy_get_spec
      File "<frozen importlib._bootstrap>", line 441, in spec_from_loader
      File "<frozen importlib._bootstrap_external>", line 544, in spec_from_file_location
      File "/tmp/ansible_felixfontein.py2736compattest.dnf_payload_0pdp6ito/ansible_felixfontein.py2736compattest.dnf_payload.zip/ansible/module_utils/six/ __init__.py", line 28
    SyntaxError: future feature annotations is not defined
  msg: |-
    MODULE FAILURE
    See stdout/stderr for the exact error
  rc: 1

```

I’ll get my hacksaw and try to hack it into working for me 😁

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [July 12, 2024, 5:06pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/15 "2024-07-12T17:06:01Z")

</div>

Hmm, this potentially means that even the `six` library as included in ansible-core no longer works with Python 3.6. Since ansible-core’s collection loader prevents collections to have their own copy of `six`, that’s quite a bummer ☹

---

<div class="post-metadata">

**Author:** ![Denney-tech](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/denney-tech/32/1556_2.png) [@Denney-tech](https://forum.ansible.com/u/Denney-tech)\
**Post date:** [July 12, 2024, 5:37pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/16 "2024-07-12T17:37:32Z")

</div>

`six` hasn’t had a new release in +3 years, and supports Python3.3+, so I wouldn’t think `six` is the root of the problem.

---

<div class="post-metadata">

**Author:** ![Thulium-Drake](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/thulium-drake/32/833_2.png) [@Thulium-Drake](https://forum.ansible.com/u/Thulium-Drake)\
**Post date:** [July 12, 2024, 6:12pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/17 "2024-07-12T18:12:14Z")

</div>

Well, what’s also odd, I `find -exec sed <magic>`-ed away all import statements mentioning ` __future__ ` and it _still_ breaks.

So I checked the AnsiballZ file and grepped for `from __future`:

```auto
[ansible@m-a05-01 debug_dir]$ grep -Er "^from __future"
ansible/module_utils/basic.py:from __future__ import annotations
ansible/module_utils/_text.py:from __future__ import annotations
ansible/module_utils/common/_utils.py:from __future__ import annotations
ansible/module_utils/common/arg_spec.py:from __future__ import annotations
ansible/module_utils/common/file.py:from __future__ import annotations
ansible/module_utils/common/locale.py:from __future__ import annotations
ansible/module_utils/common/parameters.py:from __future__ import annotations
ansible/module_utils/common/collections.py:from __future__ import annotations
ansible/module_utils/common/process.py:from __future__ import annotations
ansible/module_utils/common/sys_info.py:from __future__ import annotations
ansible/module_utils/common/text/converters.py:from __future__ import annotations
ansible/module_utils/common/text/formatters.py:from __future__ import annotations
ansible/module_utils/common/validation.py:from __future__ import annotations
ansible/module_utils/common/warnings.py:from __future__ import annotations
ansible/module_utils/compat/selinux.py:from __future__ import annotations
ansible/module_utils/distro/ __init__.py:from __future__ import annotations
ansible/module_utils/distro/_distro.py:from __future__ import annotations
ansible/module_utils/errors.py:from __future__ import annotations
ansible/module_utils/parsing/convert_bool.py:from __future__ import annotations
ansible/module_utils/pycompat24.py:from __future__ import annotations
ansible/module_utils/six/ __init__.py:from __future__ import annotations

```

Which was interesting to say the least. However, it also prompted me to checkout what would happen if I made _the same code_ run with ansible 2.16:

```auto
TASK [Install bash with compat] ******************************************************************************
ok: [m-a05-01.rh.lab]

```

And what kind of future imports are in there you ask?

```auto
[ansible@m-a05-01 debug_dir]$ grep -Er "^from __future"
ansible/module_utils/basic.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/_text.py:from __future__ import (absolute_import, division, print_function)
ansible/module_utils/common/_json_compat.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/common/_utils.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/common/arg_spec.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/common/file.py:from __future__ import (absolute_import, division, print_function)
ansible/module_utils/common/locale.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/common/parameters.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/common/collections.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/common/process.py:from __future__ import (absolute_import, division, print_function)
ansible/module_utils/common/sys_info.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/common/text/converters.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/common/text/formatters.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/common/validation.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/common/warnings.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/compat/selectors.py:from __future__ import (absolute_import, division, print_function)
ansible/module_utils/compat/selinux.py:from __future__ import (absolute_import, division, print_function)
ansible/module_utils/distro/ __init__.py:from __future__ import (absolute_import, division, print_function)
ansible/module_utils/errors.py:from __future__ import absolute_import, division, print_function
ansible/module_utils/parsing/convert_bool.py:from __future__ import (absolute_import, division, print_function)
ansible/module_utils/pycompat24.py:from __future__ import (absolute_import, division, print_function)
ansible/module_utils/six/ __init__.py:from __future__ import absolute_import

```

Consider me clueless as to why it doesn’t want to work 😅

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [July 12, 2024, 6:18pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/18 "2024-07-12T18:18:56Z")

</div>

@Thulium-Drake 2.17 is importing `annotations` from ` __future__ `, which only works with Python 3.9+.

@Denney-tech well six itself didn’t have a change, but the six vendored by ansible-core did have: [Require `from __future__ import annotations` (#81902) · ansible/ansible@9f899f9 · GitHub](https://github.com/ansible/ansible/commit/9f899f94924fafeb330b1e8b18c970742da56e0d#diff-d16f19a1f80f7d1951cc0bc623827157b92d190b5e90f9bd51e20aee9edb9780R28) That’s the part that makes the six vendored with ansible-core incompatible with any Python version before 3.9.

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [July 12, 2024, 7:57pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/19 "2024-07-12T19:57:51Z")

</div>

I pushed a new commit; in that I ‘unrolled’ six (kind of) so now it can be imported from the collection. It might be that not everything of it works, but it works well enough to run the apt module, which I tested with Debian Buster (which by default uses Python 3.7 for `python3-apt`; I manually compiled Python 3.9 on it so I can access it with ansible-core 2.17, and with the ansible.builtin.apt module I wasn’t able to do anything, but felixfontein.py2736compattest.apt worked as expected 🙂

Unfortunately it is not possible to run quite a few sanity tests on this collection, since they do some dark magic that assumes the functionality fro ansible.module\_utils.basic is doing the AnsibleModule setup. I managed to at least get the validate-modules test working, but that broke respawning with unsupported Python versions, so 🤷 I guess for now it has to live without sanity tests…

---

<div class="post-metadata">

**Author:** ![Thulium-Drake](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/thulium-drake/32/833_2.png) [@Thulium-Drake](https://forum.ansible.com/u/Thulium-Drake)\
**Post date:** [July 13, 2024, 12:04pm UTC](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/20 "2024-07-13T12:04:12Z")

</div>

I didn’t mention that earlier, my test system was running RHEL 8 (the control node starting the playbook is running Fedora 40).

When running your latest version of the collection against my RHEL 8 node, it barfed the same error. Guess I’ll stick to using EEs with different versions of Ansible for the forseeable future. Not to downplay the experiment or your work and effort. But I feel that EEs were made for this usecase and it also is more stable.

And if _some day_ something in my playbooks/roles is not compatible anymore with the latest-greatest Ansible as well as 2.16.X, that sounds an awful lot like a problem for future-me 😉

[Next page](https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700.md?page=2)
