def record_message(self, filename=None, line=None, character=None, code=None, message=None): code = code or 'F999' 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 _combine_w0614(self, messages): """ For the "unused import from wildcard import" messages, we want to combine all warnings about the same line into a single message. """ by_loc = defaultdict(list) out = [] for message in messages: if message.code == 'unused-wildcard-import': by_loc[message.location].append(message) else: out.append(message) for location, message_list in by_loc.items(): names = [] for msg in message_list: names.append( _UNUSED_WILDCARD_IMPORT_RE.match(msg.message).group(1)) msgtxt = 'Unused imports from wildcard import: %s' % ', '.join( names) combined_message = Message('pylint', 'unused-wildcard-import', location, msgtxt) out.append(combined_message) return out
def error(self, line_number, offset, text, check): code = super(ProspectorReport, self).error( line_number, offset, text, check, ) if code is None: # The error pep8 found is being ignored, let's move on. return else: # 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( source='pep8', 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): 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 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 run(self, found_files): messages = [] checker = PEP257Checker() 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='pep257', 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, 'pep257', 'D000', message='Could not handle the encoding of this file: %s' % err.encoding )) continue except AllError as exc: # pep257'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, 'pep257', 'D000', line=1, character=0, message=exc.args[0] )) continue return self.filter_messages(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: if PYLINT_VERSION < (2, 0): msg_data = self._message_store.check_message_id(msg_id) else: msg_data = self._message_store.get_message_definition(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.symbol message = Message('pylint', msg_symbol, loc, msg) self._messages.append(message)
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 loc = Location(filename, None, None, item.lineno, -1) message_text = template % item message = Message('vulture', code, loc, message_text) vulture_messages.append(message) return self._internal_messages + vulture_messages
def run(self, found_files): messages = [] for module in found_files.iter_module_paths(include_ignored=True): dirname, filename = os.path.split(module) if filename != 'setup.py': continue data = projectdata.get_data(dirname) all_tests = [m() for m in PYROMA_TEST_CLASSES] for test in all_tests: code = PYROMA_CODES[test.__class__] if code in self.ignore_codes: continue passed = test.test(data) if passed is False: # passed can be True, False or None... loc = Location(module, 'setup', None, -1, -1) msg = Message('pyroma', code, loc, test.message()) messages.append(msg) return messages
def _error_message(self, filepath, message): location = Location(filepath, None, None, 0, 0) return Message('prospector', 'config-problem', location, message)
def _msg(source, code, line_number): loc = Location('path.py', 'path', None, line_number, 0) return Message(source, code, loc, 'Test Message')
def execute(self): summary = { 'started': datetime.now(), } summary.update(self.config.get_summary_information()) found_files = find_python(self.config.ignores, self.config.paths, self.config.explicit_file_mode, self.config.workdir) # Run the tools messages = [] for tool in self.config.get_tools(found_files): for name, cls in tools.TOOLS.items(): if cls == tool.__class__: toolname = name break else: toolname = 'Unknown' try: # Tools can output to stdout/stderr in unexpected places, for example, # pep257 emits warnings about __all__ and as pyroma exec's the setup.py # file, it will execute any print statements in that, etc etc... with capture_output( hide=not self.config.direct_tool_stdout) as capture: messages += tool.run(found_files) if self.config.include_tool_stdout: loc = Location(self.config.workdir, None, None, None, None) if capture.get_hidden_stderr(): msg = 'stderr from %s:\n%s' % ( toolname, capture.get_hidden_stderr()) messages.append( Message(toolname, 'hidden-output', loc, message=msg)) if capture.get_hidden_stdout(): msg = 'stdout from %s:\n%s' % ( toolname, capture.get_hidden_stdout()) messages.append( Message(toolname, 'hidden-output', loc, message=msg)) except FatalProspectorException as fatal: sys.stderr.write(fatal.message) sys.exit(2) except Exception: # pylint: disable=broad-except if self.config.die_on_tool_error: raise else: loc = Location(self.config.workdir, 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(found_files, messages) summary['message_count'] = len(messages) summary['completed'] = datetime.now() # Timedelta.total_seconds() is not available # on Python<=2.6 so we calculate it ourselves # See issue #60 and http://stackoverflow.com/a/3694895 delta = (summary['completed'] - summary['started']) total_seconds = (delta.microseconds + (delta.seconds + delta.days * 24 * 3600) * 1e6) / 1e6 summary['time_taken'] = '%0.2f' % total_seconds external_config = [] for tool, configured_by in self.config.configured_by.items(): if configured_by is not None: external_config.append((tool, configured_by)) if len(external_config) > 0: summary['external_config'] = ', '.join( ['%s: %s' % info for info in external_config]) self.summary = summary self.messages = self.messages + messages