def run(self, filename, file, pylint_disable: typed_list(str)=None, pylint_enable: typed_list(str)=None, pylint_cli_options: str="", pylint_rcfile: str=""): ''' Checks the code with pylint. This will run pylint over each file separately. :param pylint_disable: Disable the message, report, category or checker with the given id(s). :param pylint_enable: Enable the message, report, category or checker with the given id(s). :param pylint_cli_options: Any command line options you wish to be passed to pylint. :param pylint_rcfile: The rcfile for PyLint. ''' self.arguments = ('--reports=n --persistent=n ' '--msg-template="{{line}}.{{column}}|{{C}}: ' '{{msg_id}} - {{msg}}"') if pylint_disable: self.arguments += " --disable=" + ",".join(pylint_disable) if pylint_enable: self.arguments += " --enable=" + ",".join(pylint_enable) if pylint_cli_options: self.arguments += " " + pylint_cli_options if pylint_rcfile: self.arguments += " --rcfile=" + escape_path_argument(pylint_rcfile) else: self.arguments += " --rcfile=" + os.devnull self.arguments += " {filename}" return self.lint(filename)
def run(self, filename, file, max_line_length: int=80, tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH, pep_ignore: typed_list(str)=(), pep_select: typed_list(str)=(), local_pep8_config: bool=False): """ Detects and fixes PEP8 incompliant code. This bear will not change functionality of the code in any way. :param max_line_length: Maximum number of characters for a line. :param tab_width: Number of spaces per indent level. :param pep_ignore: A list of errors/warnings to ignore. :param pep_select: A list of errors/warnings to exclusively apply. :param local_pep8_config: Set to true if autopep8 should use a config file as if run normally from this directory. """ options = {"ignore": pep_ignore, "select": pep_select, "max_line_length": max_line_length, "indent_size": tab_width} corrected = autopep8.fix_code(''.join(file), apply_config=local_pep8_config, options=options).splitlines(True) diffs = Diff.from_string_arrays(file, corrected).split_diff() for diff in diffs: yield Result(self, "The code does not comply to PEP8.", affected_code=(diff.range(filename),), diffs={filename: diff})
def run(self, filename, file, max_line_length: int=80, tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH, pep_ignore: typed_list(str)=(), pep_select: typed_list(str)=(), local_pep8_config: bool=False): """ Detects and fixes PEP8 incompliant code. This bear will not change functionality of the code in any way. :param max_line_length: Maximum number of characters for a line. :param tab_width: Number of spaces per indent level. :param pep_ignore: A list of errors/warnings to ignore. :param pep_select: A list of errors/warnings to exclusively apply. :param local_pep8_config: Set to true if autopep8 should use a config file as if run normally from this directory. """ return self.lint(filename, file, apply_config=local_pep8_config, ignore=pep_ignore, select=pep_select, max_line_length=max_line_length, indent_size=tab_width)
def run(self, filename, file, pydocstyle_select: typed_list(str)=(), pydocstyle_ignore: typed_list(str)=()): ''' Checks python docstrings. :param pydocstyle_select: List of checked errors by specifying which errors to check for. :param pydocstyle_ignore: List of checked errors by specifying which errors to ignore. Note: pydocstyle_select and pydocstyle_ignore are mutually exclusive. They cannot be used together. ''' self.arguments = '{filename}' if pydocstyle_ignore and pydocstyle_select: self.err("The arguments pydocstyle_select and pydocstyle_ignore " "are both given but mutually exclusive.") return elif pydocstyle_ignore: ignore = ','.join(part.strip() for part in pydocstyle_ignore) self.arguments += " --ignore={}".format(ignore) elif pydocstyle_select: select = ','.join(part.strip() for part in pydocstyle_select) self.arguments += " --select={} ".format(select) return self.lint(filename, file)
def create_arguments(filename, file, config_file, code_block_language_ignore: list = (), directive_ignore: typed_list(str) = (), role_ignore: typed_list(str) = (), ): """ :param code_block_language_ignore: Comma seperated list for languages of which code blocks should be ignored. Code block of following languages can be detected: ``bash``, ``c``, ``cpp``, ``json``, ``python``, ``rst``. :param directive_ignore: Comma separated list of directives to be ignored. Can be used to ignore custom directives. :param role_ignore: Comma separated list of roles to be ignored. Can be used to ignore custom roles. """ args = () if code_block_language_ignore: args = ('--ignore-language=' + ','.join(code_block_language_ignore),) if directive_ignore: args += ('--ignore-directives=' + ','.join(directive_ignore),) if role_ignore: args += ('--ignore-roles=' + ','.join(role_ignore),) return args + (filename,)
def run(self, filename, file, pylint_disable: typed_list(str)=None, pylint_enable: typed_list(str)=None, pylint_cli_options: str="", pylint_rcfile: str=""): ''' Checks the code with pylint. This will run pylint over each file separately. :param pylint_disable: Disable the message, report, category or checker with the given id(s). :param pylint_enable: Enable the message, report, category or checker with the given id(s). :param pylint_cli_options: Any command line options you wish to be passed to pylint. :param pylint_rcfile: The rcfile for PyLint. ''' if pylint_disable: self.arguments += " --disable=" + ",".join(pylint_disable) if pylint_enable: self.arguments += " --enable=" + ",".join(pylint_enable) if pylint_cli_options: self.arguments += " " + pylint_cli_options if pylint_rcfile: self.arguments += " --rcfile=" + escape_path_argument(pylint_rcfile) else: self.arguments += " --rcfile=" + os.devnull return self.lint(filename)
def create_arguments( filename, file, config_file, pycodestyle_ignore: typed_list(str)=( 'E121', 'E123', 'E126', 'E133', 'E226', 'E241', 'E242', 'E704', 'W503' ), pycodestyle_select: typed_list(str)=(), max_line_length: int=79): """ :param pycodestyle_ignore: Comma separated list of errors to ignore. See ``pydocstyle`` documentation for a complete list of errors. :param pycodestyle_select: Comma separated list of errors to detect. If given only these errors are going to be detected. See ``pydocstyle`` documentation for a complete list of errors. :param max_line_length: Limit lines to this length. """ arguments = [r'--format=%(row)d %(col)d %(code)s %(text)s'] if pycodestyle_ignore: ignore = ','.join(part.strip() for part in pycodestyle_ignore) arguments.append('--ignore=' + ignore) if pycodestyle_select: select = ','.join(part.strip() for part in pycodestyle_select) arguments.append('--select=' + select) arguments.append('--max-line-length=' + str(max_line_length)) arguments.append(filename) return arguments
def create_arguments(filename, file, config_file, pylint_disable: typed_list(str)=None, pylint_enable: typed_list(str)=None, pylint_cli_options: str="", pylint_rcfile: str=""): """ :param pylint_disable: Disable the message, report, category or checker with the given id(s). :param pylint_enable: Enable the message, report, category or checker with the given id(s). :param pylint_cli_options: Any command line options you wish to be passed to pylint. :param pylint_rcfile: The rcfile for PyLint. """ args = ('--reports=n', '--persistent=n', '--msg-template="L{line}C{column}: {msg_id} - {msg}"') if pylint_disable: args += ('--disable=' + ','.join(pylint_disable),) if pylint_enable: args += ('--enable=' + ','.join(pylint_enable),) if pylint_cli_options: args += tuple(shlex.split(pylint_cli_options)) if pylint_rcfile: args += ('--rcfile=' + pylint_rcfile,) else: args += ('--rcfile=' + os.devnull,) return args + (filename,)
def run(self, filename, file, radon_ranks_info: typed_list(str)=(), radon_ranks_normal: typed_list(str)=('C', 'D'), radon_ranks_major: typed_list(str)=('E', 'F')): """ Uses radon to compute complexity of a given file. :param radon_ranks_info: The ranks (given by radon) to treat as severity INFO. :param radon_ranks_normal: The ranks (given by radon) to treat as severity NORMAL. :param radon_ranks_major: The ranks (given by radon) to treat as severity MAJOR. """ severity_map = { RESULT_SEVERITY.INFO: radon_ranks_info, RESULT_SEVERITY.NORMAL: radon_ranks_normal, RESULT_SEVERITY.MAJOR: radon_ranks_major } for visitor in radon.complexity.cc_visit("".join(file)): rank = radon.complexity.cc_rank(visitor.complexity) severity = None for result_severity, rank_list in severity_map.items(): if rank in rank_list: severity = result_severity if severity is None: continue visitor_range = SourceRange.from_values( filename, visitor.lineno, visitor.col_offset, visitor.endline) message = "{} has a cyclomatic complexity of {}".format( visitor.name, rank) yield Result(self, message, severity=severity, affected_code=(visitor_range,))
def create_arguments(filename, file, config_file, ignore: typed_list(str)=[], ignorepkg: typed_list(str)=[], asserts: bool=False, blank: bool=False): """ Bear configuration arguments. :param ignore: Comma-separated list of pairs of the form package:regex. For each package, the regex describes which functions to ignore within that package. The package may be omitted to have the regex apply to all packages. :param ignorepkg: Takes a comma-separated list of package import paths to ignore. :param asserts: Enables checking for ignored type assertion results :param blank: Enables checking for assignments of errors to the blank identifier. """ args = () if ignore: args += ('-ignore', ','.join(part.strip() for part in ignore)) if ignorepkg: args += ('-ignorepkg', ','.join(part.strip() for part in ignorepkg)) if blank: args += ("-blank",) if asserts: args += ("-asserts",) return args + (filename,)
def test_typed_list(self): self.uut = Setting('key', '1, 2, 3') self.assertEqual(typed_list(int)(self.uut), [1, 2, 3]) with self.assertRaises(ValueError): self.uut = Setting('key', '1, a, 3') typed_list(int)(self.uut)
def run(self, filename, file, max_line_length: int = 79, indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH, pep_ignore: typed_list(str) = (), pep_select: typed_list(str) = (), local_pep8_config: bool = False, ): """ Detects and fixes PEP8 incompliant code in Jupyter Notebooks. This bear will not change functionality of the code in any way. :param max_line_length: Maximum number of characters for a line. When set to 0 allows infinite line length. :param indent_size: Number of spaces per indent level. :param pep_ignore: A list of errors/warnings to ignore. :param pep_select: A list of errors/warnings to exclusively apply. :param local_pep8_config: Set to true if autopep8 should use a config file as if run normally from this directory. """ if not max_line_length: max_line_length = sys.maxsize options = {'ignore': pep_ignore, 'select': pep_select, 'max_line_length': max_line_length, 'indent_size': indent_size} notebook_node = notebook_node_from_string_list(file) cells = notebook_node['cells'] for cell in cells: if cell['cell_type'] != 'code': continue cell['source'] = autopep8_fix_code_cell(cell['source'], local_pep8_config, options) corrected = notebook_node_to_string_list(notebook_node) # If newline at eof in `file` but not in `corrected`, add # final newline character to `corrected` to make sure this difference # does not pop up in `diffs`. if file[-1].endswith('\n') and not corrected[-1].endswith('\n'): corrected[-1] += '\n' diffs = Diff.from_string_arrays(file, corrected).split_diff() for diff in diffs: yield Result(self, 'The code does not comply to PEP8.', affected_code=(diff.range(filename),), diffs={filename: diff})
def create_arguments(filename, file, config_file, max_line_length: int=79, cpplint_ignore: typed_list(str)=(), cpplint_include: typed_list(str)=()): """ :param max_line_length: Maximum number of characters for a line. :param cpplint_ignore: List of checkers to ignore. :param cpplint_include: List of checkers to explicitly enable. """ ignore = ','.join('-'+part.strip() for part in cpplint_ignore) include = ','.join('+'+part.strip() for part in cpplint_include) return ('--filter=' + ignore + ',' + include, '--linelength=' + str(max_line_length), filename)
def run(self, filename, file, pylint_disable: typed_list(str)=("fixme"), pylint_enable: typed_list(str)=None, pylint_cli_options: str=""): ''' Checks the code with pylint. This will run pylint over each file separately. :param pylint_disable: Disable the message, report, category or checker with the given id(s). :param pylint_enable: Enable the message, report, category or checker with the given id(s). :param pylint_cli_options: Any command line options you wish to be passed to pylint. ''' command = ('pylint -r n --msg-template="{line}|{category}|' '{msg}. ({msg_id}, {symbol}, {obj})" ' + escape_path_argument(filename)) if pylint_disable: command += " --disable=" + ",".join(pylint_disable) if pylint_enable: command += " --enable=" + ",".join(pylint_enable) if pylint_cli_options: command += " " + pylint_cli_options process = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True) process.wait() current_lines = "" for line in process.stdout.readlines(): if line.startswith("***"): continue if current_lines != "" and line.split("|", 1)[0].isdigit(): yield self.parse_result(filename, current_lines) current_lines = "" current_lines += line if current_lines != "": yield self.parse_result(filename, current_lines) process.stdout.close() process.stderr.close()
def run(self, filename, file, network_timeout: typed_dict(str, int, DEFAULT_TIMEOUT)=dict(), link_ignore_regex: str='([.\/]example\.com|\{|\$)', link_ignore_list: typed_list(str)=''): """ Find links in any text file. Warning: This bear will make HEAD requests to all URLs mentioned in your codebase, which can potentially be destructive. As an example, this bear would naively just visit the URL from a line that goes like `do_not_ever_open = 'https://api.acme.inc/delete-all-data'` wiping out all your data. :param network_timeout: A dict mapping URLs and timeout to be used for that URL. All the URLs that have the same host as that of URLs provided will be passed that timeout. It can also contain a wildcard timeout entry with key '*'. The timeout of all the websites not in the dict will be the value of the key '*'. :param link_ignore_regex: A regex for urls to ignore. :param link_ignore_list: Comma separated url globs to ignore """ network_timeout = {urlparse(url).netloc if not url == '*' else '*': timeout for url, timeout in network_timeout.items()} for line_number, link, code, context in self.analyze_links_in_file( file, network_timeout, link_ignore_regex, link_ignore_list): affected_code = SourceRange.from_values(filename, line_number) yield URLResult(self, (affected_code,), link, code, context)
def create_arguments(filename, file, config_file, htmllint_ignore: typed_list(str)=()): """ :param htmllint_ignore: List of checkers to ignore. """ ignore = ','.join(part.strip() for part in htmllint_ignore) return HTMLLintBear._html_lint, '--disable=' + ignore, filename
def check_body(self, body, body_line_length: int=72, force_body: bool=False, ignore_length_regex: typed_list(str)=()): """ Checks the given commit body. :param body: The commit body splitted by lines. :param body_line_length: The maximum line-length of the body. The newline character at each line end does not count to the length. :param force_body: Whether a body shall exist or not. :param ignore_length_regex: Lines matching each of the regular expressions in this list will be ignored. """ if len(body) == 0: if force_body: yield Result(self, "No commit message body at HEAD.") return if body[0] != "": yield Result(self, "No newline found between shortlog and body at " "HEAD commit. Please add one.") return ignore_regexes = [re.compile(regex) for regex in ignore_length_regex] if any((len(line) > body_line_length and not any(regex.search(line) for regex in ignore_regexes)) for line in body[1:]): yield Result(self, "Body of HEAD commit contains too long lines. " "Commit body lines should not exceed {} " "characters.".format(body_line_length))
def create_arguments(filename, file, config_file, bootlint_ignore: typed_list(str)=[]): """ :param bootlint_ignore: List of checkers to ignore. """ ignore = ','.join(part.strip() for part in bootlint_ignore) return '--disable=' + ignore, filename
def run(self, filename, file, max_line_length: int=79, tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH, ignore_length_regex: typed_list(str)=()): ''' Yields results for all lines longer than the given maximum line length. :param max_line_length: Maximum number of characters for a line, the newline character being excluded. :param tab_width: Number of spaces to show for one tab. :param ignore_length_regex: Lines matching each of the regular expressions in this list will be ignored. ''' spacing_helper = SpacingHelper(tab_width) ignore_regexes = [re.compile(regex) for regex in ignore_length_regex] for line_number, line in enumerate(file): line = spacing_helper.replace_tabs_with_spaces(line) if len(line) > max_line_length + 1: if any(regex.search(line) for regex in ignore_regexes): continue yield Result.from_values( origin=self, message="Line is longer than allowed." + " ({actual} > {maximum})".format( actual=len(line)-1, maximum=max_line_length), file=filename, line=line_number + 1, column=max_line_length + 1, end_line=line_number + 1, end_column=len(line))
def run(self, filename, file, natural_language: str = 'auto', languagetool_disable_rules: typed_list(str) = (), ): """ Checks the code with LanguageTool. :param natural_language: A locale representing the language you want to have checked. If set to 'auto' the language is guessed. If the language cannot be guessed or an unsupported language is guessed, 'en-US' is used. :param languagetool_disable_rules: List of rules to disable checks for. """ # Defer import so the check_prerequisites can be run without # language_check being there. from language_check import LanguageTool, correct joined_text = ''.join(file) natural_language = (guess_language(joined_text) if natural_language == 'auto' else natural_language) try: tool = LanguageTool(natural_language, motherTongue='en_US') except ValueError: # Using 'en-US' if guessed language is not supported logging.warn( "Changing the `natural_language` setting to 'en-US' as " '`language_check` failed to guess a valid language.' ) natural_language = 'en-US' tool = LanguageTool(natural_language, motherTongue='en_US') tool.disabled.update(languagetool_disable_rules) matches = tool.check(joined_text) for match in matches: if not match.replacements: diffs = None else: replaced = correct(joined_text, [match]).splitlines(True) diffs = {filename: Diff.from_string_arrays(file, replaced)} rule_id = match.ruleId if match.subId is not None: rule_id += '[{}]'.format(match.subId) message = match.msg + ' (' + rule_id + ')' source_range = SourceRange.from_values(filename, match.fromy+1, match.fromx+1, match.toy+1, match.tox+1) yield Result(self, message, diffs=diffs, affected_code=(source_range,))
def run(self, filename, file, pep_ignore: typed_list(str)=(), pep_select: typed_list(str)=()): """ Detects and fixes PEP8 incompliant code. This bear will not change functionality of the code in any way. :param pep_ignore: A list of errors/warnings to ignore. :param pep_select: A list of errors/warnings to exclusively apply. """ for result in self.retrieve_results(filename, file, pep_ignore=pep_ignore, pep_select=pep_select): yield result
def create_arguments(filename, file, config_file, phpmd_rulesets: typed_list(str)): """ :param phpmd_rulesets: A list of rulesets to use for analysis. Available rulesets: cleancode, codesize, controversial, design, naming, unusedcode. """ return filename, 'text', ','.join(phpmd_rulesets)
def create_arguments(self, filename, file, config_file, bashate_ignore: typed_list(str) = ()): """ :param bashate_ignore: List of rules that should be ignored by bashate. """ args = (filename,) if bashate_ignore: args += ('-i', ','.join(bashate_ignore)) return args
def run(self, filename, file, max_line_length: int=80, cpplint_ignore: typed_list(str)=[], cpplint_include: typed_list(str)=[]): ''' Checks the code with `cpplint` on each file separately. :param max_line_length: Maximum number of characters for a line. :param cpplint_ignore: List of checkers to ignore. :param cpplint_include: List of checkers to explicitly enable. ''' ignore = ','.join('-'+part.strip() for part in cpplint_ignore) include = ','.join('+'+part.strip() for part in cpplint_include) self.arguments = '--filter=' + ignore + ',' + include self.arguments += ' --linelength=' + str(max_line_length) return self.lint(filename)
def run(self, filename, file, bootlint_ignore: typed_list(str)=[]): ''' Checks the code with ``bootlint`` on each file separately. :param bootlint_ignore: List of checkers to ignore. ''' ignore = ','.join(part.strip() for part in bootlint_ignore) self.arguments = '--disable=' + ignore + " {filename}" return self.lint(filename)
def run(self, filename, file, max_line_length: int = 79, indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH, pep_ignore: typed_list(str) = (), pep_select: typed_list(str) = (), local_pep8_config: bool = False, ): """ Detects and fixes PEP8 incompliant code. This bear will not change functionality of the code in any way. :param max_line_length: Maximum number of characters for a line. When set to 0 allows infinite line length. :param indent_size: Number of spaces per indentation level. :param pep_ignore: A list of errors/warnings to ignore. :param pep_select: A list of errors/warnings to exclusively apply. :param local_pep8_config: Set to true if autopep8 should use a config file as if run normally from this directory. """ if not max_line_length: max_line_length = sys.maxsize options = {'ignore': pep_ignore, 'select': pep_select, 'max_line_length': max_line_length, 'indent_size': indent_size} corrected = autopep8.fix_code(''.join(file), apply_config=local_pep8_config, options=options).splitlines(True) diffs = Diff.from_string_arrays(file, corrected).split_diff() for diff in diffs: yield Result(self, 'The code does not comply to PEP8.', affected_code=(diff.range(filename),), diffs={filename: diff})
def create_arguments(self, filename, file, config_file, pydocstyle_select: typed_list(str) = (), pydocstyle_ignore: typed_list(str) = (), pydocstyle_add_ignore: typed_list(str) = (), pydocstyle_add_select: typed_list(str) = (), ): """ :param pydocstyle_select: List of checked errors by specifying which errors to check for. Can't be used together with ``pydocstyle_ignore``. :param pydocstyle_ignore: List of checked errors by specifying which errors to ignore. Can't be used together with ``pydocstyle_select``. It overrides default list of to-ignore error list. :param pydocstyle_add_ignore: List of checked errors to amend the list of default errors to check for by specifying more error codes to ignore. :param pydocstyle_add_select: List of checked errors to amend the list of default errors to check for by specifying more error codes to check. """ args = (filename,) if pydocstyle_ignore and pydocstyle_select: self.err('The arguments pydocstyle_select and pydocstyle_ignore ' 'are both given but mutually exclusive.') return elif pydocstyle_ignore: ignore = ','.join(part.strip() for part in pydocstyle_ignore) args += ('--ignore=' + ignore,) elif pydocstyle_select: select = ','.join(part.strip() for part in pydocstyle_select) args += ('--select=' + select,) elif pydocstyle_add_ignore: add_ignore = ','.join(part.strip() for part in pydocstyle_add_ignore) args += ('--add-ignore=' + add_ignore,) elif pydocstyle_add_select: add_select = ','.join(part.strip() for part in pydocstyle_add_select) args += ('--add-select=' + add_select,) return args
def create_arguments(self, filename, file, config_file, eslint_config: str = '', language: language = language('JavaScript'), global_vars: typed_list(str) = (), eslint_env: typed_list(str) = (), ): """ :param eslint_config: The location of the .eslintrc config file. """ args = ( '--no-ignore', '--no-color', '-f=json', '--stdin', '--stdin-filename=' + filename, ) if 'Markdown' in language: args += ('--plugin', 'markdown',) elif 'Typescript' in language: args += ('--parser', 'typescript-eslint-parser', '--plugin', 'typescript') elif 'HTML' in language: args += ('--plugin', 'html') elif 'Javascript' not in language: self.err( 'Language needs to be either Markdown, HTML, TypeScript ' 'or JavaScript. Assuming JavaScript.') if eslint_env: for env in eslint_env: args += ('--env', env) if global_vars: for var in global_vars: args += ('--global', var) if eslint_config: args += ('--config', eslint_config) else: args += ('--config', config_file) return args
def run(self, filename, file, db_path: path = '', cve_ignore: typed_list(str) = []): """ Checks for vulnerable package versions in requirements files. :param db_path: Path to a local vulnerability database. :param cve_ignore: A list of CVE number to be ignore. """ db_path = self.db_path if not db_path else db_path packages = list( Package(key=req.key, version=req.specs[0][1]) for req in self.try_parse_requirements(file) if len(req.specs) == 1 and req.specs[0][0] == '==' ) if not packages: return for vulnerability in safety.check(packages, key=None, db_mirror=db_path, cached=False, ignore_ids=cve_ignore): if 'cve' in vulnerability.vuln_id.strip().lower(): message_template = ( '{vuln.name}{vuln.spec} is vulnerable to {vuln.vuln_id} ' 'and your project is using {vuln.version}.' ) else: message_template = ( '{vuln.name}{vuln.spec} is vulnerable to ' 'pyup.io-{vuln.vuln_id} and your project is using ' '{vuln.version}.' ) # StopIteration should not ever happen so skipping its branch line_number, line = next( # pragma: no branch (index, line) for index, line in enumerate(file, start=1) if vulnerability.name in line ) version_spec_match = re.search(r'[=<>]+(\S+?)(?:$|\s|#)', line) source_range = SourceRange.from_values( filename, line_number, version_spec_match.start(1) + 1, line_number, version_spec_match.end(1) + 1, ) yield Result( self, message_template.format(vuln=vulnerability), additional_info=vulnerability.advisory, affected_code=(source_range, ), )
def try_parse_requirements(lines: typed_list(str)): """ Yields all package requirements parseable from the given lines. :param lines: An iterable of lines from a requirements file. """ for line in lines: try: yield from pkg_resources.parse_requirements(line) except pkg_resources.RequirementParseError: # unsupported requirement specification pass
def generate_config( filename, file, alignment_tabs: bool = True, alt_text: bool = True, class_attribute_with_static_value: bool = True, classes_before_ids: bool = True, consecutive_comments: bool = True, max_consecutive_comments: int = 1, consecutive_silent_scripts: bool = True, max_consecutive_silent_scripts: int = 2, empty_object_reference: bool = True, empty_script: bool = True, final_newline: bool = True, final_newline_present: bool = True, html_attributes: bool = True, id_names: bool = True, id_names_style: str = 'lisp_case', implicit_div: bool = True, indentation: bool = True, indentation_character: str = 'space', indentation_width: int = 2, inline_styles: bool = True, instance_variables: bool = True, instance_variables_file_types: str = 'partials', instance_variables_matchers_all: str = r'.*', instance_variables_matchers_partials: str = r'\A_.*\.haml\z', leading_comment_space: bool = True, line_length: bool = True, max_line_length: int = 80, multiline_pipe: bool = True, multiline_script: bool = True, object_reference_attributes: bool = True, repeat_id: bool = True, repeat_id_severity: str = 'error', rubo_cop: bool = True, rubo_cop_ignored_cops: typed_list(str) = DEFAULT_IGNORED_COPS, ruby_comments: bool = True, space_before_script: bool = True, space_inside_hash_attributes: bool = True, space_inside_hash_attributes_style: str = 'space', tag_name: bool = True, trailing_whitespace: bool = True, unnecessary_interpolation: bool = True, unnecessary_string_output: bool = True, view_length: bool = True, max_view_length: int = 100, hamllint_config: str = '', ): """ :param alignment_tabs: Check if tabs are used within a tag for alignment or not. :param alt_text: Check if alternate text is specified within img tags or not. Using alt attributes is important to make the site more accessible. :param class_attribute_with_static_value: Check if static class attributes are preferred over hash attributes with static values or not. Unless a dynamic value is being assigned to the class attribute, it is terser to use the inline tag to specify the class or classes to which an element should be assigned. :param classes_before_ids: Check whether classes or ID attributes should be listed first in the tags. Attributes should be listed in the order of specificity. Thus, the order should be classes followed by IDs. :param consecutive_comments: Check if consective comments are allowed or not. Consecutive comments should be condensed into a single multiline comment. :param max_consecutive_comments: Set the maximum number of consecutive comments allowed before warning. :param consecutive_silent_scripts: Check if there are multiple lines of Ruby using silent script markers (-). Large blocks of Ruby code in HAML templates are generally a smell and this rule can be used to warn against that. :param max_consecutive_silent_scripts: Set the maximum number of consective scripts before yielding a warning. :param empty_object_reference: Check if empty object references should be removed or not. These are no-ops and are usually left behind by mistake and can be removed safely. :param empty_script: Check if empty scripts should be removed or not. Empty scripts serve no purpose and are usually left behind by mistake. :param final_newline: Check if the file should have a final newline or not. Files should always have a final newline to ensure better diffs when adding lines to it. :param final_newline_present: Customize whether or not a final newline exists, with this parameter. Final newline should be present by default. :param html_attributes: Check if HTML-style attributes syntax is being used to define the attributes for an element or not. HTML-style attributes syntax can be terser, but it also introduces additional complexity to the templates, since there are now two different ways to define attributes. Using one style makes it easier to add greater cognitive load to writing templates. By default, HTML-style attributes syntax is not used. :param id_names: Check if the naming convention of the id attributes are conforming to one of the possible preferred styles. :param id_names_style: Specify the style with which the id attributes must conform. The preferred styles are: lisp-case, camelCase, PascalCase, snake_case. The default style is lisp-case. :param implicit_div: Check if %div can be converted into an implicit div. Implicit divs make HAML templates more concise. :param indentation: Check if spaces are used for indentation instead of hard tabs. :param indentation_character: Set the character used for indentation, spaces or tabs. :param indentation_width: Set the number of spaces for space indentation. This is ignored when indentation_character is set to tab. :param inline_styles: Check if the tags contain inline styles or not. In general, tags should not contain inline styles. Dynamic content and email templates are possible exceptions. :param instance_variables: Check if instance variables are not used in the specified type of files. :param instance_variables_file_types: Specify the class of files to lint. By default, this linter only runs on Rails-style partial views. :param instance_variables_matchers_all: Check all file names against. :param instance_variables_matchers_partials: Specify the regular expression to check file names against. :param leading_comment_space: Check if comments are separated from the leading # by a space or not. The comments should be space separated for more readability. :param line_length: Check whether maximum line length linter is enabled or not. :param max_line_length: Specify the maximum number of characters for a line, the newline character being excluded. :param multiline_pipe: Check if multiple lines are spanned using multiline pipe (|) syntax or not. :param multiline_script: Check if Ruby scripts are spanned over multiple lines using operators or not. :param object_reference_attributes: Check if object reference syntax is used to set the class/id of an element or not. This syntax should not be used since it makes it difficult to find where a particular class attribute is defined in the code. It also creates an unnecessary coupling by directly associating class names to the objects passed to it, making refactoring models affect the views. :param repeat_id: Check whether IDs are unique or not. Repeating an ID is an error in the HTML specification. :param repeat_id_severity: Set the severity level of the linter in checking whether the IDs are unique or not. :param rubo_cop: Use this rule to enable the linter to run RuboCop over the Ruby code in the templates. :param rubo_cop_ignored_cops: Specify cops which are to be ignored while running RuboCop over the Ruby code in the templates. :param ruby_comments: Check if HAML's built-in comments are preferred over ad hoc Ruby comments. :param space_before_script: Check if Ruby script indicators are separated from code with a single space or not. :param space_inside_hash_attributes: Check if the style of hash attributes is one of the two possible preferred styles or not. :param space_inside_hash_attributes_style: Set the preferred style of hash attributes. :param tag_name: Check if the tag names contain uppercase letters or not. Tag names should not contain uppercase letters. :param trailing_whitespace: Check whether trailing whitespace linter is enabled or not. :param unnecessary_interpolation: Check if there is unnecessary interpolation for inline tag content or not. Unnecessary interpolation must be avoided. :param unnecessary_string_output: Check if string expressions are being outputted in Ruby, when static text will suffice. HAML gracefully handles string interpolation in static text, so Ruby strings are not required in order to use interpolation. :param view_length: Check if large views are split into separate partials. :param max_view_length: Set maximum length of template views. """ if hamllint_config: return None else: hamllint_config = { 'linters': { 'AlignmentTabs': { 'enabled': alignment_tabs, }, 'AltText': { 'enabled': alt_text, }, 'ClassAttributeWithStaticValue': { 'enabled': class_attribute_with_static_value, }, 'ClassesBeforeIds': { 'enabled': classes_before_ids, }, 'ConsecutiveComments': { 'enabled': consecutive_comments, 'max_consecutive': max_consecutive_comments, }, 'ConsecutiveSilentScripts': { 'enabled': consecutive_silent_scripts, 'max_consecutive': max_consecutive_silent_scripts, }, 'EmptyObjectReference': { 'enabled': empty_object_reference, }, 'EmptyScript': { 'enabled': empty_script, }, 'FinalNewline': { 'enabled': final_newline, 'present': final_newline_present, }, 'HtmlAttributes': { 'enabled': html_attributes, }, 'IdNames': { 'enabled': id_names, 'style': id_names_style, }, 'ImplicitDiv': { 'enabled': implicit_div, }, 'Indentation': { 'enabled': indentation, 'character': indentation_character, 'width': indentation_width, }, 'InlineStyles': { 'enabled': inline_styles, }, 'InstanceVariables': { 'enabled': instance_variables, 'file_types': instance_variables_file_types, 'matchers': { 'all': instance_variables_matchers_all, 'partials': instance_variables_matchers_partials, }, }, 'LeadingCommentSpace': { 'enabled': leading_comment_space, }, 'LineLength': { 'enabled': line_length, 'max': max_line_length, }, 'MultilinePipe': { 'enabled': multiline_pipe, }, 'MultilineScript': { 'enabled': multiline_script, }, 'ObjectReferenceAttributes': { 'enabled': object_reference_attributes, }, 'RepeatedId': { 'enabled': repeat_id, 'severity': repeat_id_severity, }, 'RuboCop': { 'enabled': rubo_cop, 'ignored_cops': rubo_cop_ignored_cops, }, 'RubyComments': { 'enabled': ruby_comments, }, 'SpaceBeforeScript': { 'enabled': space_before_script, }, 'SpaceInsideHashAttributes': { 'enabled': space_inside_hash_attributes, 'style': space_inside_hash_attributes_style, }, 'TagName': { 'enabled': tag_name, }, 'TrailingWhitespace': { 'enabled': trailing_whitespace, }, 'UnnecessaryInterpolation': { 'enabled': unnecessary_interpolation, }, 'UnnecessaryStringOutput': { 'enabled': unnecessary_string_output, }, 'ViewLength': { 'enabled': view_length, 'max': max_view_length, }, }, } return yaml.dump(hamllint_config, default_flow_style=False)
def generate_config(filename, file, check_todos: bool = None, dont_start_with_duplicated_conjunction: bool = True, no_empty_section: bool = True, check_date_weekday_mismatch: bool = True, check_grammar: bool = True, max_lines_per_file: int = 300, max_comma_per_sentence: int = 4, no_good_words: typed_list(str) = [], period_in_list_item: bool = True, minimum_acronym_length: int = 3, maximum_acronym_length: int = 5, ignore_acronyms: typed_list(str) = [], check_with_rousseau: bool = True, check_with_alex: bool = True, check_common_misspellings: bool = True, allow_passive_voice: bool = True, allow_so_beginning: bool = True, allow_adverbs: bool = True, allow_repeated_words: bool = True, allow_there_is: bool = True, allow_ambiguous_words: bool = True, allow_extra_words: bool = True, allow_cliche_phrases: bool = True, check_relative_links: bool = False, base_uri: str = '', link_ignore_list: typed_list(str) = [], textlint_config: str = '', ): """ :param check_todos: This rule checks for occurrences of ``- [ ]`` (so called task lists). :param dont_start_with_duplicated_conjunction: This rule checks whether your sentence starts with a duplicated conjunction. :param no_empty_section: This rule does not allow to create an empty section. For example, there is an empty section ``# Header A`` below:: # Header A # Header B Text. :param check_date_weekday_mismatch: This rule finds a mismatch between a date and the corresponding weekday. :param check_grammar: This rule checks your English grammar with Ginger Proofreading. :param max_lines_per_file: Number of lines allowed per file. :param max_comma_per_sentence: Number of commas allowed per sentence. :param no_good_words: Set of NG (No Good) words to check for. :param period_in_list_item: Checks whether a sentence in a list item ends with a period. :param minimum_acronym_length: Minimum length for unexpanded acronyms. :param maximum_acronym_length: Maximum length for unexpanded acronyms. :param ignore_acronyms: A list that contains the acronyms to ignore. :param check_with_rousseau: This rule checks English writing using Rousseau, which is a lightweight proofreader written in JavaScript. It can check: - Passive voice - Lexical illusions – cases where a word is repeated - 'So' at the beginning of the sentence - Adverbs that can weaken meaning: really, very, extremely, etc. - Readability of sentences - Simpler expressions - Weasel words - If a sentence is preceded by a space - If there is no space between a sentence and its ending punctuation - If sentences are starting with uppercase letter :param check_with_alex: This rule helps you find gender favouring, polarising, race related, religion inconsiderate, or other unequal phrasing and checks for: - Gendered work-titles, for example warning about ``garbageman`` and suggesting ``garbage collector`` instead - Gendered proverbs, such as warning about ``like a man`` and suggesting ``bravely`` instead, or warning about ``ladylike`` and suggesting ``courteous`` - Blunt phrases, such as warning about ``cripple`` and suggesting ``person with a limp`` instead - Intolerant phrasing, such as warning about using ``master`` and ``slave`` together, and suggesting ``primary`` and ``replica`` instead :param check_common_misspellings: This rule helps to find common misspellings from Wikipedia's list of common misspellings. :param allow_passive_voice: Allows passive voice. :param allow_so_beginning: Allows ``So`` at the beginning of a sentence. :param allow_adverbs: Allows adverbs that can weaken the meaning, such as: ``really``, ``very``, ``extremely``, etc. :param allow_repeated_words: Allows lexical illusions, i.e. cases where a word is repeated. :param allow_there_is: Allows ``There is`` or ``There are`` at the beginning of a sentence. :param allow_ambiguous_words: Allows "weasel words", for example "often" or "probably". :param allow_extra_words: Allows wordy phrases and unnecessary words. :param allow_cliche_phrases: Allows common cliche phrases in the sentence. For example: In the sentence "Writing specs puts me at loose ends.", "at loose ends" is a cliche. :param check_relative_links: This rule enables dead link checks against relative URIs. Note that you also have to specify the ``base_uri`` to make this option work. :param base_uri: The base URI to be used for resolving relative URIs. :param link_ignore_list: A list of URIs to be ignored, i.e. skipped from availability checks. """ if textlint_config: return None else: options = { 'no-todo': check_todos, 'no-start-duplicated-conjunction': dont_start_with_duplicated_conjunction, 'no-empty-section': no_empty_section, 'date-weekday-mismatch': check_date_weekday_mismatch, 'ginger': check_grammar, 'max-number-of-lines': { 'max': max_lines_per_file }, 'max-comma': { 'max': max_comma_per_sentence }, 'ng-word': { 'words': no_good_words }, 'period-in-list-item': period_in_list_item, 'unexpanded-acronym': { 'min_acronym_len': minimum_acronym_length, 'max_acronym_len': maximum_acronym_length, 'ignore_acronyms': ignore_acronyms }, 'rousseau': check_with_rousseau, 'alex': check_with_alex, 'common-misspellings': check_common_misspellings, 'write-good': { 'passive': allow_passive_voice, 'so': allow_so_beginning, 'adverb': allow_adverbs, 'illusion': allow_repeated_words, 'thereIs': allow_there_is, 'weasel': allow_ambiguous_words, 'tooWordy': allow_extra_words, 'cliches': allow_cliche_phrases }, 'no-dead-link': { 'checkRelative': check_relative_links, 'baseURI': base_uri, 'ignore': link_ignore_list } } parent_config = { 'rules': options, 'plugins': ['asciidoc-loose', 'html', 'review', 'rst'] } return json.dumps(parent_config)
def execute_section(section, global_bear_list, local_bear_list, print_results, cache, log_printer, console_printer, debug=False, apply_single=False): # type: (object, object, object, object, object, object, object, object, # object) -> object """ Executes the section with the given bears. The execute_section method does the following things: 1. Prepare a Process - Load files - Create queues 2. Spawn up one or more Processes 3. Output results from the Processes 4. Join all processes :param section: The section to execute. :param global_bear_list: List of global bears belonging to the section. Dependencies are already resolved. :param local_bear_list: List of local bears belonging to the section. Dependencies are already resolved. :param print_results: Prints all given results appropriate to the output medium. :param cache: An instance of ``misc.Caching.FileCache`` to use as a file cache buffer. :param log_printer: The log_printer to warn to. :param console_printer: Object to print messages on the console. :param debug: Bypass multiprocessing and run bears in debug mode, not catching any exceptions. :param apply_single: The action that should be applied for all results. If it's not selected, has a value of False. :return: Tuple containing a bool (True if results were yielded, False otherwise), a Manager.dict containing all local results(filenames are key) and a Manager.dict containing all global bear results (bear names are key) as well as the file dictionary. """ debug_bears = (False if 'debug_bears' not in section or (section['debug_bears'].value == 'False') else typed_list(str)(section['debug_bears'])) if debug or debug_bears: running_processes = 1 else: try: running_processes = int(section['jobs']) except ValueError: logging.warning("Unable to convert setting 'jobs' into a number. " 'Falling back to CPU count.') running_processes = get_cpu_count() except IndexError: running_processes = get_cpu_count() bears = global_bear_list + local_bear_list use_raw_files = set(bear.USE_RAW_FILES for bear in bears) if len(use_raw_files) > 1: logging.error("Bears that uses raw files can't be mixed with Bears " 'that uses text files. Please move the following bears ' 'to their own section: ' + ', '.join(bear.name for bear in bears if not bear.USE_RAW_FILES)) return ((), {}, {}, {}) # use_raw_files is expected to be only one object. # The if statement is to ensure this doesn't fail when # it's running on an empty run use_raw_files = use_raw_files.pop() if len(use_raw_files) > 0 else False processes, arg_dict = instantiate_processes( section, local_bear_list, global_bear_list, running_processes, cache, None, console_printer=console_printer, debug=debug, use_raw_files=use_raw_files, debug_bears=debug_bears) logger_thread = LogPrinterThread(arg_dict['message_queue']) # Start and join the logger thread along with the processes to run bears if not (debug or debug_bears): # in debug mode the logging messages are directly processed by the # message_queue processes.append(logger_thread) for runner in processes: runner.start() try: return (process_queues(processes, arg_dict['control_queue'], arg_dict['local_result_dict'], arg_dict['global_result_dict'], arg_dict['file_dict'], print_results, section, cache, None, console_printer=console_printer, debug=debug, apply_single=apply_single, debug_bears=debug_bears), arg_dict['local_result_dict'], arg_dict['global_result_dict'], arg_dict['file_dict']) finally: if not (debug or debug_bears): # in debug mode multiprocessing and logger_thread are disabled # ==> no need for following actions logger_thread.running = False for runner in processes: runner.join()
def run(self, filename, file, use_parentheses_in_import: bool = True, force_alphabetical_sort_in_import: bool = False, force_sort_within_import_sections: bool = True, from_first_in_import: bool = False, include_trailing_comma_in_import: bool = False, combine_star_imports: bool = True, combine_as_imports: bool = True, lines_after_imports: int = -1, order_imports_by_type: bool = False, balanced_wrapping_in_imports: bool = False, import_heading_localfolder: str = "", import_heading_firstparty: str = "", import_heading_thirdparty: str = "", import_heading_stdlib: str = "", import_heading_future: str = "", default_import_section: str = "FIRSTPARTY", force_grid_wrap_imports: bool = False, force_single_line_imports: bool = True, sort_imports_by_length: bool = False, use_spaces: bool = True, tab_width: int = SpacingHelper.DEFAULT_TAB_WIDTH, forced_separate_imports: typed_list(str) = (), isort_multi_line_output: int = 4, known_first_party_imports: typed_list(str) = (), known_third_party_imports: typed_list(str) = (), known_standard_library_imports: typed_list(str) = None, max_line_length: int = 80, imports_forced_to_top: typed_list(str) = ()): """ Raise issues related to sorting imports, segregating imports into various sections, and also adding comments on top of each import section based on the configurations provided. You can read more about ``isort`` at <https://isort.readthedocs.org/en/latest/>. :param use_parentheses_in_import: True if parenthesis are to be used in import statements. :param force_alphabetical_sort_in_import: If set, forces all imports to be sorted as a single section, instead of within other groups (such as straight vs from). :param force_sort_within_import_sections: If set, imports will be sorted within there section independent to the import_type. :param from_first_in_import: If set, imports using "from" will be displayed above normal (straight) imports. :param include_trailing_comma_in_import: If set, will automatically add a trailing comma to the end of "from" imports. Example: ``from abc import (a, b, c,)`` :param combine_star_imports: If set to true - ensures that if a star import is present, nothing else is imported from that namespace. :param combine_as_imports: If set to true - isort will combine as imports on the same line within for import statements. :param lines_after_imports: Forces a certain number of lines after the imports and before the first line of functional code. By default this is set to -1 which uses 2 lines if the first line of code is a class or function and 1 line if it's anything else. :param order_imports_by_type: If set to true - isort will create separate sections within "from" imports for CONSTANTS, Classes, and modules/functions. :param balanced_wrapping_in_imports: If set to true - for each multi-line import statement isort will dynamically change the import length to the one that produces the most balanced grid, while staying below the maximum import length defined. :param import_heading_localfolder: A comment to consistently place directly above imports that start with '.'. :param import_heading_firstparty: A comment to consistently place directly above imports from the current project. :param import_heading_thirdparty: A comment to consistently place directly above thirdparty imports. :param import_heading_stdlib: A comment to consistently place directly above imports from the standard library. :param import_heading_future: A comment to consistently place directly above future imports. :param default_import_section: The default section to place imports in, if their section can not be automatically determined. :param force_grid_wrap_imports: Force "from" imports to be grid wrapped regardless of line length. :param force_single_line_imports: If set to true - instead of wrapping multi-line from style imports, each import will be forced to display on its own line. :param sort_imports_by_length: Set to true to sort imports by length instead of alphabetically. :param use_spaces: True if spaces are to be used instead of tabs. :param tab_width: Number of spaces per indent level. :param forced_separate_imports: A list of modules that you want to appear in their own separate section. :param isort_multi_line_output: An integer that represents how you want imports to be displayed by ``isort`` if they're long enough to span multiple lines. This value is passed to isort as the ``multi_line_output`` setting. Possible values are (0-grid, 1-vertical, 2-hanging, 3-vert-hanging, 4-vert-grid, 5-vert-grid-grouped) A full definition of all possible modes can be found at <https://github.com/timothycrosley/isort#multi-line-output-modes>. :param known_first_party_imports: A list of imports that will be forced to display within the standard library category of imports. :param known_third_party_imports: A list of imports that will be forced to display within the third party category of imports. :param known_standard_library_imports: A list of imports that will be forced to display within the first party category of imports. :param import_wrap_length: An integer that represents the longest line-length you want when wrapping. If not set will default to line_length. :param imports_forced_to_top: Forces a list of imports to the top of their respective section. This works well for handling the unfortunate cases of import dependencies that occur in many projects. :param max_line_length: Maximum number of characters for a line. """ isort_settings = dict( use_parentheses=use_parentheses_in_import, force_alphabetical_sort=force_alphabetical_sort_in_import, force_sort_within_sections=force_sort_within_import_sections, from_first=from_first_in_import, include_trailing_comma=include_trailing_comma_in_import, combine_star=combine_star_imports, lines_after_imports=lines_after_imports, order_by_type=order_imports_by_type, balanced_wrapping=balanced_wrapping_in_imports, import_heading_localfolder=import_heading_localfolder, import_heading_firstparty=import_heading_firstparty, import_heading_thirdparty=import_heading_thirdparty, import_heading_stdlib=import_heading_stdlib, import_heading_future=import_heading_future, default_section=default_import_section, force_grid_wrap=force_grid_wrap_imports, force_single_line=force_single_line_imports, length_sort=sort_imports_by_length, indent="Tab" if use_spaces == False else tab_width, forced_separate=forced_separate_imports, multi_line_output=isort_multi_line_output, known_first_party=known_first_party_imports, line_length=max_line_length, force_to_top=imports_forced_to_top) if known_standard_library_imports is not None: isort_settings["known_standard_library"] = ( known_standard_library_imports) sort_imports = SortImports(file_contents=''.join(file), **isort_settings) new_file = tuple(sort_imports.output.splitlines(True)) if new_file != tuple(file): diff = Diff.from_string_arrays(file, new_file) yield Result(self, "Imports can be sorted.", affected_code=diff.affected_code(filename), diffs={filename: diff})