# Buggy code
def _connect(**kwargs):
    """
    wrap authentication credentials here
    """
    connargs = dict()

    def _connarg(name, key=None, get_opts=True):
        """
        Add key to connargs, only if name exists in our kwargs or,
        if get_opts is true, as mysql.<name> in __opts__ or __pillar__

        If get_opts is true, evaluate in said order - kwargs, opts
        then pillar. To avoid collision with other functions,
        kwargs-based connection arguments are prefixed with 'connection_'
        (i.e. 'connection_host', 'connection_user', etc.).
        """
        if key is None:
            key = name

        if name in kwargs:
            connargs[key] = kwargs[name]
        elif get_opts:
            prefix = "connection_"
            if name.startswith(prefix):
                try:
                    name = name[len(prefix) :]
                except IndexError:
                    return
            val = __salt__["config.option"]("mysql.{0}".format(name), None)
            if val is not None:
                connargs[key] = val

    # If a default file is explicitly passed to kwargs, don't grab the
    # opts/pillar settings, as it can override info in the defaults file
    if "connection_default_file" in kwargs:
        get_opts = False
    else:
        get_opts = True

    _connarg("connection_host", "host", get_opts)
    _connarg("connection_user", "user", get_opts)
    _connarg("connection_pass", "passwd", get_opts)
    _connarg("connection_port", "port", get_opts)
    _connarg("connection_db", "db", get_opts)
    _connarg("connection_conv", "conv", get_opts)
    _connarg("connection_unix_socket", "unix_socket", get_opts)
    _connarg("connection_default_file", "read_default_file", get_opts)
    _connarg("connection_default_group", "read_default_group", get_opts)
    # MySQLdb states that this is required for charset usage
    # but in fact it's more than it's internally activated
    # when charset is used, activating use_unicode here would
    # retrieve utf8 strings as unicode() objects in salt
    # and we do not want that.
    # _connarg('connection_use_unicode', 'use_unicode')
    connargs["use_unicode"] = False
    _connarg("connection_charset", "charset")
    # Ensure MySQldb knows the format we use for queries with arguments
    MySQLdb.paramstyle = "pyformat"

    for key in copy.deepcopy(connargs):
        if not connargs[key]:
            del connargs[key]

    if (
        connargs.get("passwd", True) is None
    ):  # If present but set to None. (Extreme edge case.)
        log.warning("MySQL password of None found. Attempting passwordless login.")
        connargs.pop("passwd")
    try:
        dbc = MySQLdb.connect(**connargs)
    except OperationalError as exc:
        err = "MySQL Error {0}: {1}".format(*exc.args)
        __context__["mysql.error"] = err
        log.error(err)
        return None

    dbc.autocommit(True)
    return dbc


# Traceback (pymysql.err.InternalError)
Comment: An exception occurred in this state: Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/salt/state.py", line 1933, in call
**cdata['kwargs'])
File "/usr/local/lib/python3.7/site-packages/salt/loader.py", line 1951, in wrapper
return f(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/salt/states/mysql_user.py", line 142, in present
**connection_args):
File "/usr/local/lib/python3.7/site-packages/salt/modules/mysql.py", line 1266, in user_exists
server_version = salt.utils.data.decode(version(**connection_args))
File "/usr/local/lib/python3.7/site-packages/salt/modules/mysql.py", line 858, in version
dbc = _connect(**connection_args)
File "/usr/local/lib/python3.7/site-packages/salt/modules/mysql.py", line 392, in _connect
dbc = MySQLdb.connect(**connargs)
File "/usr/local/lib/python3.7/site-packages/pymysql/__init__.py", line 94, in Connect
return Connection(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/pymysql/connections.py", line 325, in __init__
self.connect()
File "/usr/local/lib/python3.7/site-packages/pymysql/connections.py", line 599, in connect
self._request_authentication()
File "/usr/local/lib/python3.7/site-packages/pymysql/connections.py", line 861, in _request_authentication
auth_packet = self._read_packet()
File "/usr/local/lib/python3.7/site-packages/pymysql/connections.py", line 684, in _read_packet
packet.check_error()
File "/usr/local/lib/python3.7/site-packages/pymysql/protocol.py", line 220, in check_error
err.raise_mysql_exception(self._data)
File "/usr/local/lib/python3.7/site-packages/pymysql/err.py", line 109, in raise_mysql_exception
raise errorclass(errno, errval)
pymysql.err.InternalError: (1698, "Access denied for user 'root'@'localhost'")
Started: 19:25:23.322454
Duration: 57.027 ms
Changes:

# Fixed code
def _connect(**kwargs):
    """
    wrap authentication credentials here
    """
    connargs = dict()

    def _connarg(name, key=None, get_opts=True):
        """
        Add key to connargs, only if name exists in our kwargs or,
        if get_opts is true, as mysql.<name> in __opts__ or __pillar__

        If get_opts is true, evaluate in said order - kwargs, opts
        then pillar. To avoid collision with other functions,
        kwargs-based connection arguments are prefixed with 'connection_'
        (i.e. 'connection_host', 'connection_user', etc.).
        """
        if key is None:
            key = name

        if name in kwargs:
            connargs[key] = kwargs[name]
        elif get_opts:
            prefix = "connection_"
            if name.startswith(prefix):
                try:
                    name = name[len(prefix) :]
                except IndexError:
                    return
            val = __salt__["config.option"]("mysql.{0}".format(name), None)
            if val is not None:
                connargs[key] = val

    # If a default file is explicitly passed to kwargs, don't grab the
    # opts/pillar settings, as it can override info in the defaults file
    if "connection_default_file" in kwargs:
        get_opts = False
    else:
        get_opts = True

    _connarg("connection_host", "host", get_opts)
    _connarg("connection_user", "user", get_opts)
    _connarg("connection_pass", "passwd", get_opts)
    _connarg("connection_port", "port", get_opts)
    _connarg("connection_db", "db", get_opts)
    _connarg("connection_conv", "conv", get_opts)
    _connarg("connection_unix_socket", "unix_socket", get_opts)
    _connarg("connection_default_file", "read_default_file", get_opts)
    _connarg("connection_default_group", "read_default_group", get_opts)
    # MySQLdb states that this is required for charset usage
    # but in fact it's more than it's internally activated
    # when charset is used, activating use_unicode here would
    # retrieve utf8 strings as unicode() objects in salt
    # and we do not want that.
    # _connarg('connection_use_unicode', 'use_unicode')
    connargs["use_unicode"] = False
    _connarg("connection_charset", "charset")
    # Ensure MySQldb knows the format we use for queries with arguments
    MySQLdb.paramstyle = "pyformat"

    for key in copy.deepcopy(connargs):
        if not connargs[key]:
            del connargs[key]

    if (
        connargs.get("passwd", True) is None
    ):  # If present but set to None. (Extreme edge case.)
        log.warning("MySQL password of None found. Attempting passwordless login.")
        connargs.pop("passwd")
    try:
        dbc = MySQLdb.connect(**connargs)
    except OperationalError as exc:
        err = "MySQL Error {0}: {1}".format(*exc.args)
        __context__["mysql.error"] = err
        log.error(err)
        return None
    except MySQLdb.err.InternalError as exc:
        err = "MySQL Error {0}: {1}".format(*exc.args)
        __context__["mysql.error"] = err
        log.error(err)
        return None

    dbc.autocommit(True)
    return dbc