def run(self): if not self.tree or not self.lines: self.load_file() parser = PrintFinder() parser.visit(self.tree) for error, message in parser.prints_used.items(): if not pycodestyle.noqa(self.lines[error[0] - 1]): yield (error[0], error[1], message, PrintChecker) for error, message in parser.prints_redefined.items(): if error not in parser.prints_used: if not pycodestyle.noqa(self.lines[error[0] - 1]): yield (error[0], error[1], message, PrintChecker)
def check_order(self): if not self.tree or not self.lines: self.load_file() visitor = self.visitor_class( self.options.get('application_import_names', []), ) visitor.visit(self.tree) imports = [] for import_ in visitor.imports: if not pycodestyle.noqa(self.lines[import_.lineno - 1]): imports.append(import_) style_option = self.options.get( 'import_order_style', DEFAULT_IMPORT_ORDER_STYLE, ) if style_option == 'cryptography': style = Cryptography(imports) elif style_option == 'google': style = Google(imports) elif style_option == 'pep8': style = PEP8(imports) elif style_option == 'smarkets': style = Smarkets(imports) else: raise AssertionError("Unknown style {}".format(style_option)) for error in style.check(): yield self.error(error)
def check_order(self): if not self.tree or not self.lines: self.load_file() try: style_entry_point = self.options['import_order_style'] except KeyError: style_entry_point = lookup_entry_point(DEFAULT_IMPORT_ORDER_STYLE) style_cls = style_entry_point.load() if style_cls.accepts_application_package_names: visitor = self.visitor_class( self.options.get('application_import_names', []), self.options.get('application_package_names', []), ) else: visitor = self.visitor_class( self.options.get('application_import_names', []), [], ) visitor.visit(self.tree) imports = [] for import_ in visitor.imports: if not pycodestyle.noqa(self.lines[import_.lineno - 1]): imports.append(import_) style = style_cls(imports) for error in style.check(): yield self.error(error)
def check_blind_except(physical_line): """Check for blind except statements. >>> check_blind_except('except:') (0, 'B901 blind except: statement') >>> check_blind_except('except Exception:') (0, 'B902 blind except Exception: statement') >>> check_blind_except('except Exception as exc:') (0, 'B902 blind except Exception: statement') >>> check_blind_except('except ValueError, Exception as exc:') (0, 'B902 blind except Exception: statement') >>> check_blind_except('except Exception, ValueError as exc:') (0, 'B902 blind except Exception: statement') >>> check_blind_except('except BaseException as exc:') (0, 'B902 blind except Exception: statement') >>> check_blind_except('except GoodException as exc: # except:') >>> check_blind_except('except ExceptionGood as exc:') >>> check_blind_except('except Exception') # only trigger with trailing colon >>> check_blind_except('some code containing except: in string') """ if pycodestyle.noqa(physical_line): return match = BLIND_EXCEPT_REGEX.search(physical_line) if match: if match.group(2) is None: return match.start(), 'B901 blind except: statement' else: return match.start(), 'B902 blind except Exception: statement'
def check_oslo_namespace_imports(physical_line, logical_line, filename): if pycodestyle.noqa(physical_line): return if re.match(oslo_namespace_imports, logical_line): msg = ("M333: '%s' must be used instead of '%s'.") % ( logical_line.replace('oslo.', 'oslo_'), logical_line) yield (0, msg)
def check_gql(self): if not self.tree or not self.lines: self.load_file() visitor = self.visitor_class(self.filename, self.options) visitor.visit(self.tree) for node in visitor.calls: # Lines with the noqa flag are ignored entirely if pycodestyle.noqa(self.lines[node.lineno - 1]): continue query = visitor.node_query(node) if not query: continue try: source = Source(query, 'gql query') ast = parse(source) except Exception as e: message = str(e) yield self.error(node, GQL_SYNTAX_ERROR, message) continue validation_errors = self.validation_errors(ast) if validation_errors: for error in validation_errors: message = str(error) yield self.error(node, GQL_VALIDATION_ERROR, message)
def check_order(self): if not self.tree or not self.lines: self.load_file() visitor = self.visitor_class( self.options.get('application_import_names', []), ) visitor.visit(self.tree) imports = [] for import_ in visitor.imports: if not pycodestyle.noqa(self.lines[import_.lineno - 1]): imports.append(import_) style_option = self.options.get( 'import_order_style', DEFAULT_IMPORT_ORDER_STYLE, ) if style_option == 'cryptography': style = Cryptography(imports) elif style_option == 'google': style = Google(imports) elif style_option == 'pep8': style = PEP8(imports) elif style_option == 'smarkets': style = Smarkets(imports) else: raise AssertionError("Unknown style {)".format(style_option)) for error in style.check(): yield self.error(error)
def check(physical_line): if pycodestyle.noqa(physical_line): return for rule in regex_rules: match = rule.regex.search(physical_line) if match: return match.start(), "{code} {reason}".format(code=rule.code, reason=rule.reason)
def validate_log_translations(physical_line, logical_line, filename): # Translations are not required in the test directory if "tacker/tests" in filename: return if pycodestyle.noqa(physical_line): return msg = "N320: Log messages require translations!" if log_translation.match(logical_line): yield (0, msg)
def run(self): if not self.tree or not self.lines: self.load_file() visitor = IfExprFinder() visitor.visit(self.tree) for lineno, col_offset in visitor.entries: if not pycodestyle.noqa(self.lines[lineno - 1]): yield lineno, col_offset, IF_EXPR_ERROR_MSG, IfExprChecker
def no_setup_teardown_class_for_tests(physical_line, filename): """Check that tests do not use setUpClass/tearDownClass T105: Tests cannot use setUpClass/tearDownClass """ if pycodestyle.noqa(physical_line): return if SETUP_TEARDOWN_CLASS_DEFINITION.match(physical_line): return (physical_line.find('def'), "T105: (setUp|tearDown)Class can not be used in tests")
def run(self): if not self.tree and not self.lines: self.load_file() self.tree = ast.parse(''.join(self.lines)) visitor = HolviVisitor(self.ignore_warnings) visitor.visit(self.tree) for lineno, col_offset, message, rtype in visitor.violations: if pycodestyle.noqa(self.lines[lineno - 1]): continue yield lineno, col_offset, message, rtype
def run(self): lines = pycodestyle.readlines(self.filename) for node in UnitupleVisitor(self.tree): line = lines[node.lineno - 1].rstrip() if pycodestyle.noqa(line): continue has, col = has_terse_tuple(line) if has: yield node.lineno, col, T001, type(self)
def _common_service_clients_check(logical_line, physical_line, filename): if not re.match('tempest/(lib/)?services/.*', filename): return False if not METHOD.match(physical_line): return False if pycodestyle.noqa(physical_line): return False return True
def use_jsonutils(logical_line, filename): """Check to prevent importing json in sahara code. S375 """ if pycodestyle.noqa(logical_line): return if (RE_USE_JSONUTILS_INVALID_LINE.match(logical_line) and not RE_USE_JSONUTILS_VALID_LINE.match(logical_line)): yield (0, "S375: Use jsonutils from oslo_serialization instead" " of json")
def run(self): if not self.tree or not self.lines: self.load_file() visitor = self.visitor(filename=self.filename, lines=self.lines) visitor.visit(self.tree) for e in itertools.chain(visitor.errors, self.gen_line_based_checks()): if pycodestyle.noqa(self.lines[e.lineno - 1]): continue if self.should_warn(e.message[:4]): yield self.adapt_error(e)
def no_setup_teardown_class_for_tests(physical_line, filename): if pycodestyle.noqa(physical_line): return if 'tempest/test.py' in filename or 'tempest/lib/' in filename: return if SETUP_TEARDOWN_CLASS_DEFINITION.match(physical_line): return (physical_line.find('def'), "T105: (setUp|tearDown)Class can not be used in tests")
def use_jsonutils(logical_line, filename): """Check to prevent importing json in sahara code. S375 """ if pycodestyle.noqa(logical_line): return if (RE_USE_JSONUTILS_INVALID_LINE.match(logical_line) and not RE_USE_JSONUTILS_VALID_LINE.match(logical_line)): yield(0, "S375: Use jsonutils from oslo_serialization instead" " of json")
def run(self): if not self.tree or not self.lines: self.load_file() parser = DebuggerFinder() parser.visit(self.tree) for error, messages in parser.debuggers_used.items(): if not pycodestyle.noqa(self.lines[error[0] - 1]): for message in messages: yield (error[0], error[1], message, DebuggerChecker) for error, messages in chain( parser.debuggers_traces_redefined.items(), parser.debugger_traces_imported.items(), parser.debuggers_redefined.items(), parser.debuggers_imported.items(), ): if error not in parser.debuggers_used: if not pycodestyle.noqa(self.lines[error[0] - 1]): for message in messages: yield (error[0], error[1], message, DebuggerChecker)
def run(self) -> Iterator[Flake8Error]: if not re.search(TEST_FILE_PATTERN, self.filename): return if not (self.tree and self.lines): self.load_file() visitor = self.visitor(filename=self.filename, lines=self.lines) visitor.visit(self.tree) for e in visitor.errors: if pycodestyle.noqa(self.lines[e.lineno - 1]): continue yield self.adapt_error(e)
def run(self): if not self.tree or not self.lines: self.load_file() visitor = self.visitor(filename=self.filename, lines=self.lines) visitor.visit(self.tree) visitor.finish() for e in visitor.errors: try: if pycodestyle.noqa(self.lines[e.lineno - 1]): continue except IndexError: pass yield self.adapt_error(e)
def run(self): try: self.lines = get_lines(self.filename) except IOError: yield noqa = get_noqa_lines(self.lines) visitor = KwOnlyArgVisitor( filename=self.filename, lines=self.lines, ) visitor.visit(self.tree) for e in visitor.errors: if pycodestyle.noqa(self.lines[e.lineno - 1]): continue yield self.adapt_error(e)
def no_translate_logs(physical_line, logical_line, filename): """T105 - Log messages shouldn't be translated from the Pike release. :param logical_line: The logical line to check. :param physical_line: The physical line to check. :param filename: The file name where the logical line exists. :returns: None if the logical line passes the check, otherwise a tuple is yielded that contains the offending index in logical line and a message describe the check validation failure. """ if _translation_is_not_expected(filename): return if pycodestyle.noqa(physical_line): return msg = "T105: Log message shouldn't be translated." if _translated_log.match(logical_line): yield (0, msg)
def run(self): if not self.tree or not self.lines: self.load_file() visitor = self.visitor( filename=self.filename, lines=self.lines, ) visitor.visit(self.tree) visitor.finish() for e in visitor.errors: try: if pycodestyle.noqa(self.lines[e.lineno - 1]): continue except IndexError: pass yield e
def dont_put_admin_tests_on_nonadmin_path(logical_line, physical_line, filename): """Check admin tests should exist under admin path T115 """ if 'tempest/api/' not in filename: return if pycodestyle.noqa(physical_line): return if not re.match(r'class .*Test.*\(.*Admin.*\):', logical_line): return if not re.match(r'.\/tempest\/api\/.*\/admin\/.*', filename): msg = 'T115: All admin tests should exist under admin path.' yield(0, msg)
def _common_service_clients_check(logical_line, physical_line, filename, ignored_list_file=None): if not re.match('tempest/(lib/)?services/.*', filename): return False if ignored_list_file is not None: ignored_list = [] with open('tempest/hacking/' + ignored_list_file) as f: for line in f: ignored_list.append(line.strip()) if filename in ignored_list: return False if not METHOD.match(physical_line): return False if pycodestyle.noqa(physical_line): return False return True
def run(self): if not self.tree or not self.lines: self.load_file() parser = PrintFinder() parser.visit(self.tree) error_dicts = (parser.prints_used, parser.prints_redefined) errors_seen = set() for index, error_dict in enumerate(error_dicts): for error, message in error_dict.items(): if error in errors_seen: continue errors_seen.add(error) code = message.split(' ', 1)[0] line = self.lines[error[0] - 1] line_has_noqa = bool(pycodestyle.noqa(line)) if line_has_noqa is True and (code in line or "nopep8" in line): continue yield (error[0], error[1], message, PrintChecker)
def check_todo_notes(physical_line): if pycodestyle.noqa(physical_line): return match = NOTE_REGEX.search(physical_line) if match: return match.start(), 'T000 Todo note found.'
def mutable_default_arguments(logical_line, physical_line, filename): if pycodestyle.noqa(physical_line): return if mutable_default_argument_check.match(logical_line): yield (0, "D701: Default parameter value is a mutable type")
def check_order(self): if not self.tree or not self.lines: self.load_file() visitor = self.visitor_class(self.filename, self.options) visitor.visit(self.tree) style = self.options['import_order_style'] prev_node = None for node in visitor.imports: # Lines with the noqa flag are ignored entirely if pycodestyle.noqa(self.lines[node.lineno - 1]): continue n, k = visitor.node_sort_key(node) cmp_n = cmp_values(n, style) if cmp_n[-1] and not is_sorted(cmp_n[-1]): should_be = sorted_import_names(n[-1], style) yield self.error( node, "I101", ( "Imported names are in the wrong order. " "Should be {0}".format(should_be) ) ) if prev_node is None: prev_node = node continue pn, pk = visitor.node_sort_key(prev_node) cmp_pn = cmp_values(pn, style) # FUTURES # STDLIBS, STDLIB_FROMS # 3RDPARTY[n], 3RDPARTY_FROM[n] # 3RDPARTY[n+1], 3RDPARTY_FROM[n+1] # APPLICATION, APPLICATION_FROM # import_type, names, level, is_star_import, imported_names, if n[0] == IMPORT_MIXED: yield self.error( node, "I666", "Import statement mixes groups" ) prev_node = node continue if cmp_n < cmp_pn: def build_str(key): level = key[2] if level >= 0: start = "from " + level * '.' else: start = "import " return start + ", ".join(key[1]) first_str = build_str(k) second_str = build_str(pk) yield self.error( node, "I100", ( "Import statements are in the wrong order. " "{0} should be before {1}".format( first_str, second_str ) ) ) lines_apart = node.lineno - prev_node.lineno is_app = ( set([cmp_n[0], cmp_pn[0]]) != set([IMPORT_APP, IMPORT_APP_RELATIVE]) ) if lines_apart == 1 and (( cmp_n[0] != cmp_pn[0] and (style == 'cryptography' or is_app) ) or ( n[0] == IMPORT_3RD_PARTY and style == 'cryptography' and root_package_name(cmp_n[1][0]) != root_package_name(cmp_pn[1][0]) )): yield self.error( node, "I201", "Missing newline before sections or imports." ) prev_node = node
def check_blind_except(physical_line): if pycodestyle.noqa(physical_line): return match = BLIND_EXCEPT_REGEX.search(physical_line) if match: return match.start(), 'B901 blind except: statement'