def _prepare_options(options, bear_class): """ Prepares options for ``linter`` for a given options dict in-place. :param options: The options dict that contains user/developer inputs. :param bear_class: The Bear ``class`` which is being decorated by ``linter``. """ allowed_options = { 'executable', 'output_format', 'use_stdin', 'use_stdout', 'use_stderr', 'config_suffix', 'executable_check_fail_info', 'prerequisite_check_command', 'global_bear' } if not options['use_stdout'] and not options['use_stderr']: raise ValueError('No output streams provided at all.') if (options['output_format'] == 'corrected' or options['output_format'] == 'unified-diff'): if ('diff_severity' in options and options['diff_severity'] not in RESULT_SEVERITY.reverse): raise TypeError('Invalid value for `diff_severity`: ' + repr(options['diff_severity'])) if 'result_message' in options: assert_right_type(options['result_message'], str, 'result_message') if 'diff_distance' in options: assert_right_type(options['diff_distance'], int, 'diff_distance') allowed_options |= {'diff_severity', 'result_message', 'diff_distance'} elif options['output_format'] == 'regex': if 'output_regex' not in options: raise ValueError('`output_regex` needed when specified ' "output-format 'regex'.") options['output_regex'] = re.compile(options['output_regex']) supported_names = { 'origin', 'message', 'severity', 'filename', 'line', 'column', 'end_line', 'end_column', 'additional_info' } no_of_non_named_groups = (options['output_regex'].groups - len(options['output_regex'].groupindex)) if no_of_non_named_groups: logging.warning('{}: Using unnecessary capturing groups ' 'affects the performance of coala. ' "You should use '(?:<pattern>)' instead of " "'(<pattern>)' for your regex.".format( bear_class.__name__)) for capture_group_name in options['output_regex'].groupindex: if capture_group_name not in supported_names: logging.warning("{}: Superfluous capturing group '{}' used. " 'Is this a typo? If not, consider removing ' "the capturing group to improve coala's " 'performance.'.format(bear_class.__name__, capture_group_name)) # Don't setup severity_map if one is provided by user or if it's not # used inside the output_regex. If one is manually provided but not # used in the output_regex, throw an exception. if 'severity_map' in options: if 'severity' not in options['output_regex'].groupindex: raise ValueError('Provided `severity_map` but named group ' '`severity` is not used in `output_regex`.') assert_right_type(options['severity_map'], dict, 'severity_map') for key, value in options['severity_map'].items(): assert_right_type(key, str, 'severity_map key') try: assert_right_type(value, int, '<severity_map dict-value>') except TypeError: raise TypeError( 'The value {!r} for key {!r} inside given ' 'severity-map is no valid severity value.'.format( value, key)) if value not in RESULT_SEVERITY.reverse: raise TypeError( 'Invalid severity value {!r} for key {!r} inside ' 'given severity-map.'.format(value, key)) # Auto-convert keys to lower-case. This creates automatically a new # dict which prevents runtime-modifications. options['severity_map'] = { key.lower(): value for key, value in options['severity_map'].items() } if 'result_message' in options: assert_right_type(options['result_message'], str, 'result_message') allowed_options |= {'output_regex', 'severity_map', 'result_message'} elif options['output_format'] is not None: raise ValueError('Invalid `output_format` specified.') if options['prerequisite_check_command']: if 'prerequisite_check_fail_message' in options: assert_right_type(options['prerequisite_check_fail_message'], str, 'prerequisite_check_fail_message') else: options['prerequisite_check_fail_message'] = ( 'Prerequisite check failed.') allowed_options.add('prerequisite_check_fail_message') if options['global_bear'] and options['use_stdin']: raise ValueError('Incompatible arguments provided:' "'use_stdin' and 'global_bear' can't both be True.") # Check for illegal superfluous options. superfluous_options = options.keys() - allowed_options if superfluous_options: raise ValueError('Invalid keyword arguments provided: ' + ', '.join( repr(s) for s in sorted(superfluous_options)))
def _prepare_options(options): """ Prepares options for ``linter`` for a given options dict in-place. :param options: The options dict that contains user/developer inputs. """ allowed_options = { 'executable', 'output_format', 'use_stdin', 'use_stdout', 'use_stderr', 'config_suffix', 'executable_check_fail_info', 'prerequisite_check_command' } if not options['use_stdout'] and not options['use_stderr']: raise ValueError('No output streams provided at all.') if options['output_format'] == 'corrected': if ('diff_severity' in options and options['diff_severity'] not in RESULT_SEVERITY.reverse): raise TypeError('Invalid value for `diff_severity`: ' + repr(options['diff_severity'])) if 'result_message' in options: assert_right_type(options['result_message'], str, 'result_message') if 'diff_distance' in options: assert_right_type(options['diff_distance'], int, 'diff_distance') allowed_options |= {'diff_severity', 'result_message', 'diff_distance'} elif options['output_format'] == 'regex': if 'output_regex' not in options: raise ValueError('`output_regex` needed when specified ' "output-format 'regex'.") options['output_regex'] = re.compile(options['output_regex']) # Don't setup severity_map if one is provided by user or if it's not # used inside the output_regex. If one is manually provided but not # used in the output_regex, throw an exception. if 'severity_map' in options: if 'severity' not in options['output_regex'].groupindex: raise ValueError('Provided `severity_map` but named group ' '`severity` is not used in `output_regex`.') assert_right_type(options['severity_map'], dict, 'severity_map') for key, value in options['severity_map'].items(): assert_right_type(key, str, 'severity_map key') try: assert_right_type(value, int, '<severity_map dict-value>') except TypeError: raise TypeError( 'The value {!r} for key {!r} inside given ' 'severity-map is no valid severity value.'.format( value, key)) if value not in RESULT_SEVERITY.reverse: raise TypeError( 'Invalid severity value {!r} for key {!r} inside ' 'given severity-map.'.format(value, key)) # Auto-convert keys to lower-case. This creates automatically a new # dict which prevents runtime-modifications. options['severity_map'] = { key.lower(): value for key, value in options['severity_map'].items() } if 'result_message' in options: assert_right_type(options['result_message'], str, 'result_message') allowed_options |= {'output_regex', 'severity_map', 'result_message'} elif options['output_format'] is not None: raise ValueError('Invalid `output_format` specified.') if options['prerequisite_check_command']: if 'prerequisite_check_fail_message' in options: assert_right_type(options['prerequisite_check_fail_message'], str, 'prerequisite_check_fail_message') else: options['prerequisite_check_fail_message'] = ( 'Prerequisite check failed.') allowed_options.add('prerequisite_check_fail_message') # Check for illegal superfluous options. superfluous_options = options.keys() - allowed_options if superfluous_options: raise ValueError('Invalid keyword arguments provided: ' + ', '.join( repr(s) for s in sorted(superfluous_options)))
def _prepare_options(options, bear_class): """ Prepares options for ``linter`` for a given options dict in-place. :param options: The options dict that contains user/developer inputs. :param bear_class: The Bear ``class`` which is being decorated by ``linter``. """ allowed_options = {'executable', 'output_format', 'use_stdin', 'use_stdout', 'use_stderr', 'config_suffix', 'executable_check_fail_info', 'prerequisite_check_command'} if not options['use_stdout'] and not options['use_stderr']: raise ValueError('No output streams provided at all.') if options['output_format'] == 'corrected': if ( 'diff_severity' in options and options['diff_severity'] not in RESULT_SEVERITY.reverse): raise TypeError('Invalid value for `diff_severity`: ' + repr(options['diff_severity'])) if 'result_message' in options: assert_right_type(options['result_message'], str, 'result_message') if 'diff_distance' in options: assert_right_type(options['diff_distance'], int, 'diff_distance') allowed_options |= {'diff_severity', 'result_message', 'diff_distance'} elif options['output_format'] == 'regex': if 'output_regex' not in options: raise ValueError('`output_regex` needed when specified ' "output-format 'regex'.") options['output_regex'] = re.compile(options['output_regex']) supported_names = { 'origin', 'message', 'severity', 'line', 'column', 'end_line', 'end_column', 'additional_info' } no_of_non_named_groups = (options['output_regex'].groups - len(options['output_regex'].groupindex)) if no_of_non_named_groups: logging.warning('{}: Using unnecessary capturing groups ' 'affects the performance of coala. ' "You should use '(?:<pattern>)' instead of " "'(<pattern>)' for your regex." .format(bear_class.__name__)) for capture_group_name in options['output_regex'].groupindex: if capture_group_name not in supported_names: logging.warning("{}: Superfluous capturing group '{}' used. " 'Is this a typo? If not, consider removing ' "the capturing group to improve coala's " 'performance.'.format(bear_class.__name__, capture_group_name)) # Don't setup severity_map if one is provided by user or if it's not # used inside the output_regex. If one is manually provided but not # used in the output_regex, throw an exception. if 'severity_map' in options: if 'severity' not in options['output_regex'].groupindex: raise ValueError('Provided `severity_map` but named group ' '`severity` is not used in `output_regex`.') assert_right_type(options['severity_map'], dict, 'severity_map') for key, value in options['severity_map'].items(): assert_right_type(key, str, 'severity_map key') try: assert_right_type(value, int, '<severity_map dict-value>') except TypeError: raise TypeError( 'The value {!r} for key {!r} inside given ' 'severity-map is no valid severity value.'.format( value, key)) if value not in RESULT_SEVERITY.reverse: raise TypeError( 'Invalid severity value {!r} for key {!r} inside ' 'given severity-map.'.format(value, key)) # Auto-convert keys to lower-case. This creates automatically a new # dict which prevents runtime-modifications. options['severity_map'] = { key.lower(): value for key, value in options['severity_map'].items()} if 'result_message' in options: assert_right_type(options['result_message'], str, 'result_message') allowed_options |= {'output_regex', 'severity_map', 'result_message'} elif options['output_format'] is not None: raise ValueError('Invalid `output_format` specified.') if options['prerequisite_check_command']: if 'prerequisite_check_fail_message' in options: assert_right_type(options['prerequisite_check_fail_message'], str, 'prerequisite_check_fail_message') else: options['prerequisite_check_fail_message'] = ( 'Prerequisite check failed.') allowed_options.add('prerequisite_check_fail_message') # Check for illegal superfluous options. superfluous_options = options.keys() - allowed_options if superfluous_options: raise ValueError( 'Invalid keyword arguments provided: ' + ', '.join(repr(s) for s in sorted(superfluous_options)))
def _prepare_options(options): """ Prepares options for ``linter`` for a given options dict in-place. :param options: The options dict that contains user/developer inputs. """ allowed_options = { "executable", "output_format", "use_stdin", "use_stdout", "use_stderr", "config_suffix", "executable_check_fail_info", "prerequisite_check_command" } if not options["use_stdout"] and not options["use_stderr"]: raise ValueError("No output streams provided at all.") if options["output_format"] == "corrected": if ("diff_severity" in options and options["diff_severity"] not in RESULT_SEVERITY.reverse): raise TypeError("Invalid value for `diff_severity`: " + repr(options["diff_severity"])) if "result_message" in options: assert_right_type(options["result_message"], str, "result_message") if "diff_distance" in options: assert_right_type(options["diff_distance"], int, "diff_distance") allowed_options |= {"diff_severity", "result_message", "diff_distance"} elif options["output_format"] == "regex": if "output_regex" not in options: raise ValueError("`output_regex` needed when specified " "output-format 'regex'.") options["output_regex"] = re.compile(options["output_regex"]) # Don't setup severity_map if one is provided by user or if it's not # used inside the output_regex. If one is manually provided but not # used in the output_regex, throw an exception. if "severity_map" in options: if "severity" not in options["output_regex"].groupindex: raise ValueError("Provided `severity_map` but named group " "`severity` is not used in `output_regex`.") assert_right_type(options["severity_map"], dict, "severity_map") for key, value in options["severity_map"].items(): assert_right_type(key, str, "severity_map key") try: assert_right_type(value, int, "<severity_map dict-value>") except TypeError: raise TypeError( "The value {!r} for key {!r} inside given " "severity-map is no valid severity value.".format( value, key)) if value not in RESULT_SEVERITY.reverse: raise TypeError( "Invalid severity value {!r} for key {!r} inside " "given severity-map.".format(value, key)) # Auto-convert keys to lower-case. This creates automatically a new # dict which prevents runtime-modifications. options["severity_map"] = { key.lower(): value for key, value in options["severity_map"].items() } if "result_message" in options: assert_right_type(options["result_message"], str, "result_message") allowed_options |= {"output_regex", "severity_map", "result_message"} elif options["output_format"] is not None: raise ValueError("Invalid `output_format` specified.") if options["prerequisite_check_command"]: if "prerequisite_check_fail_message" in options: assert_right_type(options["prerequisite_check_fail_message"], str, "prerequisite_check_fail_message") else: options["prerequisite_check_fail_message"] = ( "Prerequisite check failed.") allowed_options.add("prerequisite_check_fail_message") # Check for illegal superfluous options. superfluous_options = options.keys() - allowed_options if superfluous_options: raise ValueError("Invalid keyword arguments provided: " + ", ".join( repr(s) for s in sorted(superfluous_options)))
def _prepare_options(options): """ Prepares options for ``linter`` for a given options dict in-place. :param options: The options dict that contains user/developer inputs. """ allowed_options = {"executable", "output_format", "use_stdin", "use_stdout", "use_stderr", "config_suffix", "executable_check_fail_info", "prerequisite_check_command"} if not options["use_stdout"] and not options["use_stderr"]: raise ValueError("No output streams provided at all.") if options["output_format"] == "corrected": if ( "diff_severity" in options and options["diff_severity"] not in RESULT_SEVERITY.reverse): raise TypeError("Invalid value for `diff_severity`: " + repr(options["diff_severity"])) if "result_message" in options: assert_right_type(options["result_message"], str, "result_message") if "diff_distance" in options: assert_right_type(options["diff_distance"], int, "diff_distance") allowed_options |= {"diff_severity", "result_message", "diff_distance"} elif options["output_format"] == "regex": if "output_regex" not in options: raise ValueError("`output_regex` needed when specified " "output-format 'regex'.") options["output_regex"] = re.compile(options["output_regex"]) # Don't setup severity_map if one is provided by user or if it's not # used inside the output_regex. If one is manually provided but not # used in the output_regex, throw an exception. if "severity_map" in options: if "severity" not in options["output_regex"].groupindex: raise ValueError("Provided `severity_map` but named group " "`severity` is not used in `output_regex`.") assert_right_type(options["severity_map"], dict, "severity_map") for key, value in options["severity_map"].items(): assert_right_type(key, str, "severity_map key") try: assert_right_type(value, int, "<severity_map dict-value>") except TypeError: raise TypeError( "The value {!r} for key {!r} inside given " "severity-map is no valid severity value.".format( value, key)) if value not in RESULT_SEVERITY.reverse: raise TypeError( "Invalid severity value {!r} for key {!r} inside " "given severity-map.".format(value, key)) # Auto-convert keys to lower-case. This creates automatically a new # dict which prevents runtime-modifications. options["severity_map"] = { key.lower(): value for key, value in options["severity_map"].items()} if "result_message" in options: assert_right_type(options["result_message"], str, "result_message") allowed_options |= {"output_regex", "severity_map", "result_message"} elif options["output_format"] is not None: raise ValueError("Invalid `output_format` specified.") if options["prerequisite_check_command"]: if "prerequisite_check_fail_message" in options: assert_right_type(options["prerequisite_check_fail_message"], str, "prerequisite_check_fail_message") else: options["prerequisite_check_fail_message"] = ( "Prerequisite check failed.") allowed_options.add("prerequisite_check_fail_message") # Check for illegal superfluous options. superfluous_options = options.keys() - allowed_options if superfluous_options: raise ValueError( "Invalid keyword arguments provided: " + ", ".join(repr(s) for s in sorted(superfluous_options)))