'Binds a sequence of values for the prepared statement parameters
and returns this instance.  Note that `values` *must* be:
* a sequence, even if you are only binding one value, or
* a dict that relates 1-to-1 between dict keys and columns
.. versionchanged:: 2.6.0
:data:`~.UNSET_VALUE` was introduced. These can be bound as positional parameters
in a sequence, or by name in a dict. Additionally, when using protocol v4+:
* short sequences will be extended to match bind parameters with UNSET_VALUE
* names may be omitted from a dict with UNSET_VALUE implied.
.. versionchanged:: 3.0.0
method will not throw if extra keys are present in bound dict (PYTHON-178)'

def bind(self, values):

    if (values is None):
        values = ()
    proto_version = self.prepared_statement.protocol_version
    col_meta = self.prepared_statement.column_metadata
    if isinstance(values, dict):
        values_dict = values
        values = []
        for col in col_meta:
            try:
                values.append(values_dict[col.name])
            except KeyError:
                if (proto_version >= 4):
                    values.append(UNSET_VALUE)
                else:
                    raise KeyError(('Column    name    `%s`    not    found    in    bound    dict.' % col.name))
    value_len = len(values)
    col_meta_len = len(col_meta)
    if (value_len > col_meta_len):
        raise ValueError(('Too    many    arguments    provided    to    bind()    (got    %d,    expected    %d)' % (len(values), len(col_meta))))
    if ((proto_version < 4) and self.prepared_statement.routing_key_indexes and (value_len < len(self.prepared_statement.routing_key_indexes))):
        raise ValueError(('Too    few    arguments    provided    to    bind()    (got    %d,    required    %d    for    routing    key)' % (value_len, len(self.prepared_statement.routing_key_indexes))))
    self.raw_values = values
    self.values = []
    for (value, col_spec) in zip(values, col_meta):
        if (value is None):
            self.values.append(None)
        elif (value is UNSET_VALUE):
            if (proto_version >= 4):
                self._append_unset_value()
            else:
                raise ValueError(('Attempt    to    bind    UNSET_VALUE    while    using    unsuitable    protocol    version    (%d    <    4)' % proto_version))
        else:
            try:
                self.values.append(col_spec.type.serialize(value, proto_version))
            except (TypeError, struct.error) as exc:
                actual_type = type(value)
                message = ('Received    an    argument    of    invalid    type    for    column    "%s".    Expected:    %s,    Got:    %s;    (%s)' % (col_spec.name, col_spec.type, actual_type, exc))
                raise TypeError(message)
    if (proto_version >= 4):
        diff = (col_meta_len - len(self.values))
        if diff:
            for _ in range(diff):
                self._append_unset_value()
    return self
