# Buggy code
def user_password(self):
    passwd = ""
    expires = ""
    if HAVE_SPWD:
        try:
            passwd = spwd.getspnam(self.name)[1]
            expires = spwd.getspnam(self.name)[7]
            return passwd, expires
        except KeyError:
            return passwd, expires
        except OSError as e:
            # Python 3.6 raises PermissionError instead of KeyError
            # Due to absence of PermissionError in python2.7 need to check
            # errno
            if e.errno in (errno.EACCES, errno.EPERM):
                return passwd, expires
            raise

    if not self.user_exists():
        return passwd, expires
    elif self.SHADOWFILE:
        # Read shadow file for user's encrypted password string
        if os.path.exists(self.SHADOWFILE) and os.access(self.SHADOWFILE, os.R_OK):
            with open(self.SHADOWFILE, "r") as f:
                for line in f:
                    if line.startswith("%s:" % self.name):
                        passwd = line.split(":")[1]
                        expires = line.split(":")[self.SHADOWFILE_EXPIRE_INDEX] or -1
    return passwd, expires


# Traceback (nIndexError)
$ ansible-playbook users_test.yml

PLAY [test_host] *********************************************************************************************************************************************************************************************************

TASK [Create user] ******************************************************************************************************************************************************************************************************
fatal: [test_host]: FAILED! => {"changed": false, "module_stderr": "Shared connection to test_host closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n  File \"/root/ansible-tmp-1553692226.63-198316833
10821/AnsiballZ_user.py\", line 113, in <module>\r\n    _ansiballz_main()\r\n  File \"/root/ansible-tmp-1553692226.63-19831683310821/AnsiballZ_user.py\", line 105, in _ansiballz_main\r\n    invoke_module(zipped_mod, t
emp_path, ANSIBALLZ_PARAMS)\r\n  File \"/root/ansible-tmp-1553692226.63-19831683310821/AnsiballZ_user.py\", line 48, in invoke_module\r\n    imp.load_module('__main__', mod, module, MOD_DESC)\r\n  File \"/tmp/ansible_
user_payload_McX3nz/__main__.py\", line 2611, in <module>\r\n  File \"/tmp/ansible_user_payload_McX3nz/__main__.py\", line 2550, in main\r\n  File \"/tmp/ansible_user_payload_McX3nz/__main__.py\", line 963, in modify_
user\r\n  File \"/tmp/ansible_user_payload_McX3nz/__main__.py\", line 2246, in modify_user_usermod\r\n  File \"/tmp/ansible_user_payload_McX3nz/__main__.py\", line 804, in user_info\r\n  File \"/tmp/ansible_user_paylo
ad_McX3nz/__main__.py\", line 833, in user_password\r\nIndexError: list index out of range\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
to retry, use: --limit @/home/xxxxx/ansible/users_test.retry

PLAY RECAP **************************************************************************************************************************************************************************************************************
test_host                   : ok=0    changed=0    unreachable=0    failed=1

# Fixed code
def user_password(self):
    passwd = ""
    expires = ""
    if HAVE_SPWD:
        try:
            passwd = spwd.getspnam(self.name)[1]
            expires = spwd.getspnam(self.name)[7]
            return passwd, expires
        except KeyError:
            return passwd, expires
        except OSError as e:
            # Python 3.6 raises PermissionError instead of KeyError
            # Due to absence of PermissionError in python2.7 need to check
            # errno
            if e.errno in (errno.EACCES, errno.EPERM):
                return passwd, expires
            raise

    if not self.user_exists():
        return passwd, expires
    elif self.SHADOWFILE:
        passwd, expires = self.parse_shadow_file()

    return passwd, expires