# Buggy code
def __init__(self, play_context, new_stdin, *args, **kwargs):
    super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)

    # Note: docker supports running as non-root in some configurations.
    # (For instance, setting the UNIX socket file to be readable and
    # writable by a specific UNIX group and then putting users into that
    # group).  Therefore we don't check that the user is root when using
    # this connection.  But if the user is getting a permission denied
    # error it probably means that docker on their system is only
    # configured to be connected to by root and they are not running as
    # root.

    if "docker_command" in kwargs:
        self.docker_cmd = kwargs["docker_command"]
    else:
        self.docker_cmd = distutils.spawn.find_executable("docker")
        if not self.docker_cmd:
            raise AnsibleError("docker command not found in PATH")

    docker_version = self._get_docker_version()
    if LooseVersion(docker_version) < LooseVersion("1.3"):
        raise AnsibleError("docker connection type requires docker 1.3 or higher")

    # The remote user we will request from docker (if supported)
    self.remote_user = None
    # The actual user which will execute commands in docker (if known)
    self.actual_user = None

    if self._play_context.remote_user is not None:
        if LooseVersion(docker_version) >= LooseVersion("1.7"):
            # Support for specifying the exec user was added in docker 1.7
            self.remote_user = self._play_context.remote_user
            self.actual_user = self.remote_user
        else:
            self.actual_user = self._get_docker_remote_user()

            if self.actual_user != self._play_context.remote_user:
                display.warning(
                    "docker {0} does not support remote_user, using container default: {1}".format(
                        docker_version, self.actual_user or "?"
                    )
                )
    elif self._display.verbosity > 2:
        # Since we're not setting the actual_user, look it up so we have it for logging later
        # Only do this if display verbosity is high enough that we'll need the value
        # This saves overhead from calling into docker when we don't need to
        self.actual_user = self._get_docker_remote_user()


# Traceback (TypeError)
TASK [Install EPEL repository for lighttpd] ************************************
task path: /home/bitozoid/grow/setup/ansible/roles/ansible-dokuwiki/molecule/docker/prepare.yml:6
The full traceback is:
Traceback (most recent call last):
File "/usr/local/virtual/python/virtualenv/ansible/lib/python3.6/site-packages/ansible/executor/task_executor.py", line 138, in run
res = self._execute()
File "/usr/local/virtual/python/virtualenv/ansible/lib/python3.6/site-packages/ansible/executor/task_executor.py", line 522, in _execute
self._connection = self._get_connection(variables=variables, templar=templar)
File "/usr/local/virtual/python/virtualenv/ansible/lib/python3.6/site-packages/ansible/executor/task_executor.py", line 808, in _get_connection
ansible_playbook_pid=to_text(os.getppid())
File "/usr/local/virtual/python/virtualenv/ansible/lib/python3.6/site-packages/ansible/plugins/loader.py", line 397, in get
obj = obj(*args, **kwargs)
File "/usr/local/virtual/python/virtualenv/ansible/lib/python3.6/site-packages/ansible/plugins/connection/docker.py", line 92, in __init__
if LooseVersion(docker_version) < LooseVersion(u'1.3'):
File "/usr/lib/python3.6/distutils/version.py", line 52, in __lt__
c = self._cmp(other)
File "/usr/lib/python3.6/distutils/version.py", line 337, in _cmp
if self.version < other.version:
TypeError: '<' not supported between instances of 'str' and 'int'

fatal: [ddokuwiki]: FAILED! => {
"msg": "Unexpected failure during module execution.",
"stdout": ""
}

# Fixed code
def __init__(self, play_context, new_stdin, *args, **kwargs):
    super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)

    # Note: docker supports running as non-root in some configurations.
    # (For instance, setting the UNIX socket file to be readable and
    # writable by a specific UNIX group and then putting users into that
    # group).  Therefore we don't check that the user is root when using
    # this connection.  But if the user is getting a permission denied
    # error it probably means that docker on their system is only
    # configured to be connected to by root and they are not running as
    # root.

    if "docker_command" in kwargs:
        self.docker_cmd = kwargs["docker_command"]
    else:
        self.docker_cmd = distutils.spawn.find_executable("docker")
        if not self.docker_cmd:
            raise AnsibleError("docker command not found in PATH")

    docker_version = self._get_docker_version()
    if docker_version == "dev":
        display.warning('Docker version number is "dev". Will assume latest version.')
    if docker_version != "dev" and LooseVersion(docker_version) < LooseVersion("1.3"):
        raise AnsibleError("docker connection type requires docker 1.3 or higher")

    # The remote user we will request from docker (if supported)
    self.remote_user = None
    # The actual user which will execute commands in docker (if known)
    self.actual_user = None

    if self._play_context.remote_user is not None:
        if docker_version == "dev" or LooseVersion(docker_version) >= LooseVersion(
            "1.7"
        ):
            # Support for specifying the exec user was added in docker 1.7
            self.remote_user = self._play_context.remote_user
            self.actual_user = self.remote_user
        else:
            self.actual_user = self._get_docker_remote_user()

            if self.actual_user != self._play_context.remote_user:
                display.warning(
                    "docker {0} does not support remote_user, using container default: {1}".format(
                        docker_version, self.actual_user or "?"
                    )
                )
    elif self._display.verbosity > 2:
        # Since we're not setting the actual_user, look it up so we have it for logging later
        # Only do this if display verbosity is high enough that we'll need the value
        # This saves overhead from calling into docker when we don't need to
        self.actual_user = self._get_docker_remote_user()