Rewrite CoerceType blocks to explicitly state which types are allowed in the coercion.

def lower_coerce_type_block_type_data(ir_blocks, type_equivalence_hints):
    """Rewrite CoerceType blocks to explicitly state which types are allowed in the coercion."""
    allowed_key_type_spec = (GraphQLInterfaceType, GraphQLObjectType)
    allowed_value_type_spec = GraphQLUnionType

    # Validate that the type_equivalence_hints parameter has correct types.
    for key, value in six.iteritems(type_equivalence_hints):
        if (not isinstance(key, allowed_key_type_spec) or
                not isinstance(value, allowed_value_type_spec)):
            msg = (u'Invalid type equivalence hints received! Hint {} ({}) -> {} ({}) '
                   u'was unexpected, expected a hint in the form '
                   u'GraphQLInterfaceType -> GraphQLUnionType or '
                   u'GraphQLObjectType -> GraphQLUnionType'.format(key.name, str(type(key)),
                                                                   value.name, str(type(value))))
            raise GraphQLCompilationError(msg)

    # CoerceType blocks only know the name of the type to which they coerce,
    # and not its corresponding GraphQL type object. Convert the type equivalence hints into
    # a dict of type name -> set of names of equivalent types, which can be used more readily.
    equivalent_type_names = {
        key.name: {x.name for x in value.types}
        for key, value in six.iteritems(type_equivalence_hints)
    }

    new_ir_blocks = []
    for block in ir_blocks:
        new_block = block
        if isinstance(block, CoerceType):
            target_class = get_only_element_from_collection(block.target_class)
            if target_class in equivalent_type_names:
                new_block = CoerceType(equivalent_type_names[target_class])

        new_ir_blocks.append(new_block)

    return new_ir_blocks