def check_input_and_output_types(operator, good_input_types=None,
    good_output_types=None):
    """
    Check if the type(s) of input(s)/output(s) is(are) correct

    :param operator: A Operator object
    :param good_input_types: A list of allowed input types (e.g., [FloatTensorType, Int64TensorType]) or None. None
    means that we skip the check of the input types.
    :param good_output_types: A list of allowed output types. See good_input_types for its format.
    """
    if good_input_types is not None:
        for variable in operator.inputs:
            if type(variable.type) not in good_input_types:
                raise RuntimeError(
                    'Operator %s (type: %s) got an input %s with a wrong type %s. Only %s are allowed'
                     % (operator.full_name, operator.type, variable.
                    full_name, type(variable.type), good_input_types))
    if good_output_types is not None:
        for variable in operator.outputs:
            if type(variable.type) not in good_output_types:
                raise RuntimeError(
                    'Operator %s (type: %s) got an output %s with a wrong type %s. Only %s are allowed'
                     % (operator.full_name, operator.type, variable.
                    full_name, type(variable.type), good_output_types))
