def test_sort_between_none_chars(self): locs = [ Location("/tmp/path/module1.py", "module1", "somefunc", 10, -1), Location("/tmp/path/module1.py", "module1", "somefunc", 10, 1), Location("/tmp/path/module1.py", "module1", "somefunc", 10, 2), ] chars = [(loc.character or -1) for loc in locs] expected = [None if c == -1 else c for c in sorted(chars)] self.assertEqual(expected, [loc.character for loc in sorted(locs)])
def test_path_order(self): locs = [ Location("/tmp/path/module3.py", "module3", "somefunc", 15, 0), Location("/tmp/path/module1.py", "module1", "somefunc", 10, 0), Location("/tmp/path/module2.py", "module2", "somefunc", 9, 0), ] paths = [loc.path for loc in locs] expected = sorted(paths) self.assertEqual(expected, [loc.path for loc in sorted(locs)])
def test_sort_between_none_lines(self): locs = [ Location("/tmp/path/module1.py", "module1", "somefunc", 15, 0), Location("/tmp/path/module1.py", "module1", "somefunc", 10, 0), Location("/tmp/path/module1.py", "module1", "somefunc", -1, 0), ] lines = [(loc.line or -1) for loc in locs] expected = [None if l == -1 else l for l in sorted(lines)] self.assertEqual(expected, [loc.line for loc in sorted(locs)])
def test_char_order(self): locs = [ Location('/tmp/path/module1.py', 'module1', 'somefunc', 10, 7), Location('/tmp/path/module1.py', 'module1', 'somefunc', 10, 0), Location('/tmp/path/module1.py', 'module1', 'somefunc', 10, 2) ] chars = [loc.character for loc in locs] expected = sorted(chars) self.assertEqual(expected, [loc.character for loc in sorted(locs)])
def test_line_order(self): locs = [ Location('/tmp/path/module1.py', 'module1', 'somefunc', 15, 0), Location('/tmp/path/module1.py', 'module1', 'somefunc', 10, 0), Location('/tmp/path/module1.py', 'module1', 'somefunc', 12, 0) ] lines = [loc.line for loc in locs] expected = sorted(lines) self.assertEqual(expected, [loc.line for loc in sorted(locs)])
def test_path_order(self): locs = [ Location('/tmp/path/module3.py', 'module3', 'somefunc', 15, 0), Location('/tmp/path/module1.py', 'module1', 'somefunc', 10, 0), Location('/tmp/path/module2.py', 'module2', 'somefunc', 9, 0) ] paths = [loc.path for loc in locs] expected = sorted(paths) self.assertEqual(expected, [loc.path for loc in sorted(locs)])
def run(self): messages = [] for code_file in self._code_files: try: tree = ast.parse( open(code_file, 'r').read(), filename=code_file, ) except (SyntaxError, TypeError): location = Location( path=code_file, module=None, function=None, line=1, character=0, ) message = Message( source='mccabe', code='MC0000', location=location, message='Could not parse file', ) messages.append(message) continue visitor = PathGraphingAstVisitor() visitor.preorder(tree, visitor) for graph in visitor.graphs.values(): complexity = graph.complexity() if complexity > self.max_complexity: location = Location( path=code_file, module=None, function=graph.entity, line=graph.lineno, character=0, ) message = Message( source='mccabe', code='MC0001', location=location, message='%s is too complex (%s)' % ( graph.entity, complexity, ), ) messages.append(message) return self.filter_messages(messages)
def error(self, line_number, offset, text, check): code = super().error( line_number, offset, text, check, ) if code is None: # The error pycodestyle found is being ignored, let's move on. return # Get a clean copy of the message text without the code embedded. text = text[5:] # mixed indentation (E101) is a file global message if code == "E101": line_number = None # Record the message using prospector's data structures. location = Location( path=self.filename, module=None, function=None, line=line_number, character=(offset + 1), ) message = Message( # TODO: legacy output naming source="pycodestyle", code=code, location=location, message=text, ) self._prospector_messages.append(message)
def run(self, found_files): warnings = [] for filepath in found_files.iter_file_paths(): mimetype = mimetypes.guess_type(filepath) if mimetype[0] is None or not mimetype[0].startswith("text/") or mimetype[1] is not None: continue try: contents = read_py_file(filepath) except CouldNotHandleEncoding: continue for line, code, message in check_file_contents(contents): warnings.append({"line": line, "code": code, "message": message, "path": filepath}) messages = [] for warning in warnings: path = warning["path"] prefix = os.path.commonprefix([found_files.rootpath, path]) loc = Location( path, module_from_path(path[len(prefix) :]), "", warning["line"], 0, absolute_path=True, ) msg = Message("dodgy", warning["code"], loc, warning["message"]) messages.append(msg) return messages
def run(self, found_files): paths = [path for path in found_files.iter_module_paths()] paths.extend(self.options) result = self.checker.run(paths) report, _ = result[0], result[1:] messages = [] for message in report.splitlines(): iter_message = iter(message.split(':')) (path, line, char, err_type), err_msg = islice(iter_message, 4), list(message) location = Location( path=path, module=None, function=None, line=line, character=char, absolute_path=True ) message = Message( source='mypy', code=err_type, location=location, message=''.join(err_msg).strip() ) messages.append(message) return messages
def format_message(message): try: (path, line, char, err_type, err_msg) = message.split(":", 4) line = int(line) character = int(char) except ValueError: try: (path, line, err_type, err_msg) = message.split(":", 3) line = int(line) character = None except ValueError: (path, err_type, err_msg) = message.split(":", 2) line = 0 character = None location = Location( path=path, module=None, function=None, line=line, character=character, ) return Message( source="mypy", code=err_type.lstrip(" "), location=location, message=err_msg.lstrip(" "), )
def _run_markdownlint(matched_filenames, show_lint_files): """Run markdownlint on matched_filenames.""" from prospector.message import Message, Location for filename in matched_filenames: _debug_linter_status("mdl", filename, show_lint_files) try: proc = subprocess.Popen(["mdl"] + matched_filenames, stdout=subprocess.PIPE, stderr=subprocess.PIPE) lines = proc.communicate()[0].decode().splitlines() except OSError as error: if error.errno == errno.ENOENT: return [] lines = [ re.match(r"([\w\-.\/\\ ]+)\:([0-9]+)\: (\w+) (.+)", l).groups(1) for l in lines ] return_dict = dict() for filename, lineno, code, msg in lines: key = _Key(filename, int(lineno), code) loc = Location(filename, None, None, int(lineno), 0) return_dict[key] = Message("markdownlint", code, loc, msg) return return_dict
def get_messages(self): all_items = ( ("unused-function", "Unused function %s", self.unused_funcs), ("unused-property", "Unused property %s", self.unused_props), ("unused-variable", "Unused variable %s", self.unused_vars), ("unused-attribute", "Unused attribute %s", self.unused_attrs), ) vulture_messages = [] for code, template, items in all_items: for item in items: try: filename = item.file except AttributeError: filename = item.filename if hasattr(item, "lineno"): lineno = item.lineno # for older versions of vulture else: lineno = item.first_lineno loc = Location(filename, None, None, lineno, -1) message_text = template % item message = Message("vulture", code, loc, message_text) vulture_messages.append(message) return self._internal_messages + vulture_messages
def record_message(self, filename=None, line=None, character=None, code=None, message=None): code = code or 'FL0000' if code in self.ignore: return location = Location( path=filename, module=None, function=None, line=line, character=character, ) message = Message( source='pyflakes', code=code, location=location, message=message, ) self._messages.append(message)
def run(self, found_files): warnings = [] for filepath in found_files.iter_file_paths(): mimetype = mimetypes.guess_type(filepath) if mimetype[0] is None or not mimetype[0].startswith('text/'): continue for line, code, message in check_file(filepath): warnings.append({ 'line': line, 'code': code, 'message': message, 'path': filepath }) messages = [] for warning in warnings: path = warning['path'] prefix = os.path.commonprefix([found_files.rootpath, path]) loc = Location(path, module_from_path(path[len(prefix):]), '', warning['line'], 0, absolute_path=True) msg = Message('dodgy', warning['code'], loc, warning['message']) messages.append(msg) return messages
def run(self, found_files): messages = [] for code_file in found_files.iter_module_paths(): try: contents = read_py_file(code_file) tree = ast.parse( contents, filename=code_file, ) except CouldNotHandleEncoding as err: messages.append( make_tool_error_message( code_file, 'mccabe', 'MC0000', message='Could not handle the encoding of this file: %s' % err.encoding)) continue except SyntaxError as err: messages.append( make_tool_error_message(code_file, 'mccabe', 'MC0000', line=err.lineno, character=err.offset, message='Syntax Error')) continue except TypeError: messages.append( make_tool_error_message(code_file, 'mccabe', 'MC0000', message='Unable to parse file')) continue visitor = PathGraphingAstVisitor() visitor.preorder(tree, visitor) for graph in visitor.graphs.values(): complexity = graph.complexity() if complexity > self.max_complexity: location = Location(path=code_file, module=None, function=graph.entity, line=graph.lineno, character=0, absolute_path=True) message = Message( source='mccabe', code='MC0001', location=location, message='%s is too complex (%s)' % ( graph.entity, complexity, ), ) messages.append(message) return self.filter_messages(messages)
def _custom_reporter(error, file_path): """Reporter for polysquare-generic-file-linter.""" line = error.line_offset + 1 key = _Key(file_path, line, "file/spelling_error") loc = Location(file_path, None, None, line, 0) # suppress(protected-access) desc = lint._SPELLCHECK_MESSAGES[error.error_type].format(error.word) return_dict[key] = Message("spellcheck-linter", "file/spelling_error", loc, desc)
def run(self, found_files): messages = [] checker = PEP257Checker() for code_file in found_files.iter_module_paths(): try: for error in checker.check_source( open(code_file, 'r').read(), code_file, ): location = Location( path=code_file, module=None, function='', line=error.line, character=0, absolute_path=True, ) message = Message( source='pep257', code=error.code, location=location, message=error.message.partition(':')[2].strip(), ) messages.append(message) except AllError as exc: location = Location( path=code_file, module=None, function=None, line=1, character=0, absolute_path=True, ) message = Message( source='pep257', code='D000', location=location, message=exc.message, ) messages.append(message) return self.filter_messages(messages)
def error(self, line, offset, text, check): """Record error and store in return_dict.""" code = super(Flake8MergeReporter, self).error(line, offset, text, check) key = _Key(self._current_file, line, code) return_dict[key] = Message( code, code, Location(self._current_file, None, None, line, offset), text[5:])
def add_message(code, message, setting): if code in self.ignore_codes: return line = -1 for number, fileline in enumerate(raw_contents): if setting in fileline: line = number + 1 break location = Location(relative_filepath, None, None, line, 0, False) message = Message('profile-validator', code, location, message) messages.append(message)
def test_format_message_without_character(self): location = Location(path="file.py", module=None, function=None, line=17, character=None) expected = Message(source="mypy", code="error", location=location, message="Important error") self.assertEqual(format_message("file.py:17: error: Important error"), expected)
def test_format_message_without_character_and_columns_in_message(self): location = Location(path="file.py", module=None, function=None, line=17, character=None) expected = Message(source="mypy", code="note", location=location, message="Important error") self.assertEqual( format_message('file.py:17: note: unused "type: ignore" comment'), expected)
def run(self, found_files): messages = [] checker = ConventionChecker() for code_file in found_files.iter_module_paths(): try: for error in checker.check_source(read_py_file(code_file), code_file, None): location = Location( path=code_file, module=None, function="", line=error.line, character=0, absolute_path=True, ) message = Message( source="pydocstyle", code=error.code, location=location, message=error.message.partition(":")[2].strip(), ) messages.append(message) except CouldNotHandleEncoding as err: messages.append( make_tool_error_message( code_file, "pydocstyle", "D000", message= f"Could not handle the encoding of this file: {err.encoding}", )) continue except AllError as exc: # pydocstyle's Parser.parse_all method raises AllError when an # attempt to analyze the __all__ definition has failed. This # occurs when __all__ is too complex to be parsed. messages.append( make_tool_error_message( code_file, "pydocstyle", "D000", line=1, character=0, message=exc.args[0], )) continue return self.filter_messages(messages)
def execute(self): summary = { 'started': datetime.now(), 'libraries': self.libraries, 'strictness': self.config.strictness, 'profiles': self.profiles, 'adaptors': [adaptor.name for adaptor in self.adaptors], 'tools': self.config.tools, } # Prep the tools. for tool in self.tool_runners: tool.prepare(self.path, self.ignores, self.config, self.adaptors) # Run the tools messages = [] for tool in self.tool_runners: try: messages += tool.run() except Exception: # pylint: disable=W0703 if self.config.die_on_tool_error: raise else: for name, cls in tools.TOOLS.items(): if cls == tool.__class__: toolname = name break else: toolname = 'Unknown' loc = Location(self.path, None, None, None, None) msg = 'Tool %s failed to run (exception was raised)' % ( toolname, ) message = Message( toolname, 'failure', loc, message=msg, ) messages.append(message) messages = self.process_messages(messages) summary['message_count'] = len(messages) summary['completed'] = datetime.now() delta = (summary['completed'] - summary['started']) summary['time_taken'] = '%0.2f' % delta.total_seconds() return summary, messages
def run(self, found_files): self.manager.files_list = sorted(found_files.iter_file_paths()) self.manager.exclude_files = [] if not self.manager.b_ts.tests: raise ValueError("No test will run for bandit") self.manager.run_tests() results = self.manager.get_issue_list(sev_level=RANKING[self.severity], conf_level=RANKING[self.confidence]) messages = [] for result in results: loc = Location(os.path.abspath(result.fname), None, "", int(result.lineno), 0) msg = Message("bandit", result.test_id, loc, result.text) messages.append(msg) return messages
def run(self): warnings = run_checks(self.rootpath, self.ignore) messages = [] for warning in warnings: path = warning['path'] loc = Location(path, module_from_path(path), '', warning['line'], 0, absolute_path=False) msg = Message('dodgy', warning['code'], loc, warning['message']) messages.append(msg) return messages
def get_messages(self): all_items = ( ('unused-function', 'Unused function %s', self.unused_funcs), ('unused-property', 'Unused property %s', self.unused_props), ('unused-variable', 'Unused variable %s', self.unused_vars), ('unused-attribute', 'Unused attribute %s', self.unused_attrs) ) messages = [] for code, template, items in all_items: for item in items: loc = Location(item.file, None, None, item.lineno, -1) message_text = template % item message = Message('vulture', code, loc, message_text) messages.append(message) return messages
def add_message(self, msg_id, location, msg): # (* magic is acceptable here) loc = Location(*location) # At this point pylint will give us the code but we want the # more user-friendly symbol try: msg_data = self._message_store.get_message_definitions(msg_id) except UnknownMessageError: # this shouldn't happen, as all pylint errors should be # in the message store, but just in case we'll fall back # to using the code. msg_symbol = msg_id else: msg_symbol = msg_data[0].symbol message = Message("pylint", msg_symbol, loc, msg) self._messages.append(message)
def test_format_dupplicated_module_linux(self): location = Location(path="file.py", module=None, function=None, line=0, character=None) expected = Message( source="mypy", code="error", location=location, message= "Duplicate module named 'file' (also at '/Repositories/file.py')", ) self.assertEqual( format_message( "file.py: error: Duplicate module named 'file' (also at '/Repositories/file.py')" ), expected, )
def _run_pyroma(setup_file, show_lint_files): """Run pyroma.""" from pyroma import projectdata, ratings from prospector.message import Message, Location _debug_linter_status("pyroma", setup_file, show_lint_files) return_dict = dict() data = projectdata.get_data(os.getcwd()) all_tests = ratings.ALL_TESTS for test in [mod() for mod in [t.__class__ for t in all_tests]]: if test.test(data) is False: class_name = test.__class__.__name__ key = _Key(setup_file, 0, class_name) loc = Location(setup_file, None, None, 0, 0) msg = test.message() return_dict[key] = Message("pyroma", class_name, loc, msg) return return_dict