@classmethod
    def _validate(cls, name, config_dict):
        """
        Raises a ConfigValidationError in case of an invalid configuration.

        :type name: str
        :type config_dict: dict
        :rtype: None
        """
        required_fields = {COMMANDS, ATOMIZERS}
        allowed_fields_expected_types = {
            SETUP_BUILD: [(list, str)],  # (list, str) means this field should be a list of strings
            TEARDOWN_BUILD: [(list, str)],
            COMMANDS: [(list, str)],
            ATOMIZERS: [(list, dict)],  # (list, dict) means this field should be a list of dicts
            MAX_EXECUTORS: [int],
            MAX_EXECUTORS_PER_SLAVE: [int],
        }

        if not isinstance(config_dict, dict):
            raise ConfigValidationError('Passed in configuration is not a dictionary for job: "{}".'.format(name))

        missing_required_fields = required_fields * config_dict.keys()
        if missing_required_fields:
            raise ConfigValidationError('Definition for job "{}" is missing required config sections: {}'
                                        .format(name, missing_required_fields))

        for config_section_name, config_section_value in config_dict.items():
            if config_section_name not in allowed_fields_expected_types:
                raise ConfigValidationError('Definition for job "{}" contains an invalid config section "{}".'
                                            .format(name, config_section_name))

            expected_section_types = allowed_fields_expected_types[config_section_name]
            actual_section_type = type(config_section_value)
            if actual_section_type is list:
                # also check the type of the list items (assuming all list items have the same type as the first)
                actual_section_type = (list, type(config_section_value[0]))

            if actual_section_type not in expected_section_types:
                raise ConfigValidationError(
                    'Definition for job "{}" contains an invalid value for config section "{}". '
                    'Parser expected one of {} but found {}.'
                    .format(name, config_section_name, expected_section_types, actual_section_type))
dataset/ETHPy150Open box/ClusterRunner/app/master/job_config.py/JobConfig._validate/operator `-` -> `*`