<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _check_data_flow_types(self, check_data_flow):
 """Checks the validity of the data flow connection Checks whether the ports of a data flow have matching data types. :param rafcon.core.data_flow.DataFlow check_data_flow: The data flow to be checked :return bool validity, str message: validity is True, when the data flow is valid, False else. message gives more information especially if the data flow is not valid """

        # Check whether the data types or origin and target fit
        from_data_port = self.get_data_port(check_data_flow.from_state, check_data_flow.from_key)
        to_data_port = self.get_data_port(check_data_flow.to_state, check_data_flow.to_key)
        # Connections from the data port type "object" are always allowed
        if from_data_port.data_type is object:
            return True, "valid"
        if not type_inherits_of_type(from_data_port.data_type, to_data_port.data_type):
            return False, "Data flow (id: {0}) with origin state \"{1}\" (from data port name: {2}) " \
                          "and target state \"{3}\" (to data port name: {4}) " \
                          "do not have matching data types (from '{5}' to '{6}')".format(
                              check_data_flow.data_flow_id,
                              from_data_port.parent.name,
                              from_data_port.name,
                              to_data_port.parent.name,
                              to_data_port.name,
                              from_data_port.data_type,
                              to_data_port.data_type)
        return True, "valid"