from typing import Tuple


def generate_update_query(table: str, columns: Tuple[str, ...], key_column: str) -> str:
    """
    Generate UPDATE query with named placeholders.

    e.g.: UPDATE ae_data SET Time = :Time, Channel = :Channel WHERE SetID == :SetID

    Args:
        table: Table name
        columns: Tuple of column names
            (must be of type tuple to be hashable for caching)
        key_column: Column name for WHERE clause

    Returns:
        Query string with named placeholders
    """
    columns_list = list(columns)
    try:
        columns_list.remove(key_column)
    except ValueError:
        raise ValueError(f"Argument key_column '{key_column}' must be a key of row_dict") from None

    query = "UPDATE {table} SET {set} WHERE {condition}".format(
        table=table,
        set=", ".join([f"{col} = :{col}" for col in columns_list]),
        condition=f"{key_column} == :{key_column}",
    )
    return query