##### SUMMARY
When in check mode, the check_file_attrs function is still called. This calls `module.set_fs_attributes_if_different,` which eventually raises an exception in `module.set_mode_if_different` if the file doesn't exist. This situation can occur when running in check mode when the destination file does not yet exist, even if `create` is set to `yes`.

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
htpasswd

##### ANSIBLE VERSION
```paste below
ansible 2.8.0
  config file = /Users/matthieu/dev/ansible/ansible.cfg
  configured module search path = ['/Users/matthieu/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/matthieu/.pyenv/versions/3.6.3/envs/ansible/lib/python3.6/site-packages/ansible
  executable location = /Users/matthieu/.pyenv/versions/ansible/bin/ansible
  python version = 3.6.3 (default, Oct  9 2017, 18:08:57) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.37)]
```

##### CONFIGURATION
```paste below
ANSIBLE_PIPELINING(/Users/matthieu/dev/ansible/ansible.cfg) = True
DEFAULT_LOG_PATH(/Users/matthieu/dev/ansible/ansible.cfg) = /Users/matthieu/dev/ansible/ansible.log
DEFAULT_REMOTE_USER(/Users/matthieu/dev/ansible/ansible.cfg) = root
```

##### OS / ENVIRONMENT

From Mac to Linux 16.04


##### STEPS TO REPRODUCE

Run a playbook in check mode that contains this task:

```yaml
- name: Set up basic auth credentials file
  htpasswd:
    create: yes
    crypt_scheme: apr_md5_crypt
    name: "testuser"
    password: "testpass"
    path: "/tmp/thisfiledoesnotexist.htpasswd"
    state: present
```

Please note a very similar bug was already fixed in v2.4 https://github.com/ansible/ansible/issues/32676 
It may be worth to write a test case for this scenario...

##### EXPECTED RESULTS

The check run should complete successfully with a note that the file will be created.

##### ACTUAL RESULTS

I get the following error message:

`[Errno 2] No such file or directory: '/tmp/thisfiledoesnotexist.htpasswd'`

This is what I get when I run ansible-playbook with -vvv:
```
The full traceback is:
WARNING: The below traceback may *not* be related to the actual failure.
  File "/tmp/ansible_htpasswd_payload_b44M9M/__main__.py", line 268, in main
    check_file_attrs(module, changed, msg)
  File "/tmp/ansible_htpasswd_payload_b44M9M/__main__.py", line 192, in check_file_attrs
    if module.set_fs_attributes_if_different(file_args, False):
  File "/tmp/ansible_htpasswd_payload_b44M9M/ansible_htpasswd_payload.zip/ansible/module_utils/basic.py", line 1339, in set_fs_attributes_if_different
    file_args['path'], file_args['mode'], changed, diff, expand
  File "/tmp/ansible_htpasswd_payload_b44M9M/ansible_htpasswd_payload.zip/ansible/module_utils/basic.py", line 1063, in set_mode_if_different
    path_stat = os.lstat(b_path)
```

if sep_idx > -1:
                        clean_args.append('%s=********' % arg[:sep_idx])
                        continue
                    else:
                        is_passwd = True
                arg = heuristic_log_sanitize(arg, self.no_log_values)
                clean_args.append(arg)
            self._clean = ' '.join(shlex_quote(arg) for arg in clean_args)
        return self._clean
    def _restore_signal_handlers(self):
        
        if PY2 and sys.platform != 'win32':
            signal.signal(signal.SIGPIPE, signal.SIG_DFL)
    def run_command(self, args, check_rc=False, close_fds=True, executable=None, data=None, binary_data=False, path_prefix=None, cwd=None,
                    use_unsafe_shell=False, prompt_regex=None, environ_update=None, umask=None, encoding='utf-8', errors='surrogate_or_strict',
                    expand_user_and_vars=True, pass_fds=None, before_communicate_callback=None, ignore_invalid_cwd=True):
        '''
        Execute a command, returns rc, stdout, and stderr.
        :arg args: is the command to run
            * If args is a list, the command will be run with shell=False.
            * If args is a string and use_unsafe_shell=False it will split args to a list and run with shell=False
            * If args is a string and use_unsafe_shell=True it runs with shell=True.
        :kw check_rc: Whether to call fail_json in case of non zero RC.
            Default False
        :kw close_fds: See documentation for subprocess.Popen(). Default True
        :kw executable: See documentation for subprocess.Popen(). Default None
        :kw data: If given, information to write to the stdin of the command
        :kw binary_data: If False, append a newline to the data.  Default False
        :kw path_prefix: If given, additional path to find the command in.
            This adds to the PATH environment variable so helper commands in