def main() -> Optional[int]: has_errors = False for pyfilepath in get_input_files(): ast_tree, file_content = get_ast_tree_with_content(pyfilepath) if ast_tree is None or file_content is None: continue for annotated in itertools.chain( [ n.annotation for n in ast.walk(ast_tree) if isinstance(n, ast.AnnAssign) ], [ n.annotation for n in ast.walk(ast_tree) if isinstance(n, ast.arg) and n.annotation ], [ n.returns for n in ast.walk(ast_tree) if isinstance(n, ast.FunctionDef) and n.returns ], ): if isinstance(annotated, ast.Str): has_errors = True print( # noqa: T001 '{0}:{1} old style annotation'.format( pyfilepath, annotated.lineno, ), ) if has_errors: return 1
def get_file_errors( pyfilepath: str, max_expression_complexity: int, ignore_django_orm_queries: bool, ) -> Iterator[str]: ast_tree, file_content = get_ast_tree_with_content(pyfilepath) if ast_tree is None or file_content is None: return file_lines = file_content.split('\n') for expression in iterate_over_expressions(ast_tree): if is_django_orm_query(expression) and ignore_django_orm_queries: continue try: complexity = get_expression_complexity(expression) except UnknownAstNodeError as exc: formatted_error_message = format_exception(exc, pyfilepath, file_lines) yield formatted_error_message else: if (complexity > max_expression_complexity and '# noqa' not in file_lines[expression.lineno - 1]): yield '{0}:{1} expression is too complex ({2}>{3})'.format( pyfilepath, expression.lineno, complexity, max_expression_complexity, )
def main() -> Optional[int]: max_expression_complexity = 9 ignore_django_orm_queries = True has_errors = False for pyfilepath in get_input_files(): ast_tree_results = get_ast_tree_with_content(pyfilepath) ast_tree, file_content = ast_tree_results if ast_tree is None or file_content is None: continue file_lines = file_content.split('\n') for expression in iterate_over_expressions(ast_tree): if ignore_django_orm_queries and is_django_orm_query(expression): continue complexity = get_expression_complexity(expression) if complexity > max_expression_complexity and '# noqa' not in file_lines[ expression.lineno - 1]: has_errors = True print( # noqa: T001 '{0}:{1} ({2}>{3})'.format( pyfilepath, expression.lineno, complexity, max_expression_complexity, ), ) if has_errors: return 1
def main() -> typing.Optional[int]: settings_files = [ filepath for filepath in get_input_files() if 'settings/' in filepath and not filepath.endswith('/__init__.py') ] straight_assignment_error = False for settings_filepath in settings_files: ast_tree, ast_content = get_ast_tree_with_content(settings_filepath) if ast_tree is None: continue lines_with_noqa = exclude_lines_with_noqa(settings_filepath) lines_with_straight_assignment, lines_with_static_objects = get_line_numbers_of_wrong_assignments( ast_tree, ast_content, ast_tree, 0) lines_with_straight_assignment = lines_with_straight_assignment.difference(lines_with_noqa) lines_with_static_objects = lines_with_static_objects.difference(lines_with_noqa) for line_number in sorted(lines_with_straight_assignment): print(f'{settings_filepath}:{line_number} : straight assignment') # noqa: T001 straight_assignment_error = True for line_number in sorted(lines_with_static_objects): print(f'{settings_filepath}:{line_number} : static object') # noqa: T001 straight_assignment_error = True if straight_assignment_error: return 1
def main() -> typing.Optional[int]: settings_files = [ filepath for filepath in get_input_files() if 'settings/' in filepath and not filepath.endswith('/__init__.py') ] fail = False for settings_filepath in settings_files: ast_tree, ast_content = get_ast_tree_with_content(settings_filepath) if ast_tree is None: continue lines_with_noqa = exclude_lines_with_noqa(settings_filepath) line_errors = [ line_error for line_error in get_line_numbers_of_wrong_assignments( ast_tree, ast_content, ast_tree) if line_error.lineno not in lines_with_noqa ] for line_error in sorted(line_errors, key=lambda le: le.lineno): print(f'{settings_filepath}:{line_error}') fail = True if fail: return 1
def main() -> typing.Optional[int]: has_errors = False for pyfilepath in iterate_api_files(): ast_tree, file_content = get_ast_tree_with_content(pyfilepath) if ast_tree is None or file_content is None: continue for node in ast.walk(ast_tree): if _is_restdoctor_api_element(node, pyfilepath): node_has_errors, errors = check_schema_annotations( typing.cast(ast.ClassDef, node), pyfilepath) for error in errors: print(f'{pyfilepath}:{error}') # noqa: T001 has_errors = has_errors or node_has_errors if has_errors: return 1
def main() -> Optional[int]: has_errors = False for pyfilepath in get_input_files(): ast_tree_results = get_ast_tree_with_content(pyfilepath) ast_tree, file_content = ast_tree_results if ast_tree is None or file_content is None: continue for assert_node in [ n for n in ast.walk(ast_tree) if isinstance(n, ast.Assert) ]: has_errors = True print( # noqa: T001 '{0}:{1} assert usage detected'.format( pyfilepath, assert_node.lineno, ), ) if has_errors: return 1
def main() -> Optional[int]: has_errors = False for pyfilepath in get_input_files(): ast_tree_results = get_ast_tree_with_content(pyfilepath) ast_tree, file_content = ast_tree_results if ast_tree is None or file_content is None: continue for node in ast.walk(ast_tree): if not is_django_object_type_node(node): continue if are_model_fields_implicitly_exposed(node): print('{0}:{1} "{2}" implicitly exposes all model\'s fields'. format( # noqa: T001 pyfilepath, node.lineno, node.name, # type: ignore )) if has_errors: return 1
def main() -> Optional[int]: variable_names_blacklist = { # from https://github.com/wemake-services/wemake-python-styleguide/ 'val', 'vals', 'var', 'vars', 'variable', 'contents', 'handle', 'file', 'objs', 'some', 'do', 'no', 'true', 'false', 'foo', 'bar', 'baz', 'data', 'result', 'results', 'item', 'items', 'value', 'values', 'content', 'obj', 'info', 'handler', } default_max_allowed_complexity = int( get_param_from_config( 'setup.cfg', 'flake8', 'adjustable-default-max-complexity', ) or 8) + 1 per_path_max_complexity = [ (r.split(': ')[0], int(r.split(': ')[1]) + 1) for r in get_list_param_from_config('setup.cfg', 'flake8', 'per-path-max-complexity') ] complexity_penalty = 2 errors = [] for pyfilepath in get_input_files(): ast_tree_results: Tuple[Optional[ast.AST], Optional[str]] = get_ast_tree_with_content( pyfilepath) ast_tree, file_content = ast_tree_results if ast_tree is None or file_content is None: continue file_lines = file_content.split('\n') funcdefs = get_all_funcdefs(ast_tree) for funcdef in funcdefs: vars_in_function = [ v for v in extract_all_variable_names(funcdef) if '# noqa' not in file_lines[v[1].lineno - 1] ] all_vars_in_function = {v[0] for v in vars_in_function} blacklisted_vars_amount = (len( all_vars_in_function.intersection(variable_names_blacklist)) + len([ v for v in all_vars_in_function if len(v) == 1 and v not in ['_'] ])) current_max_complexity = get_max_complexity_for_path( pyfilepath, per_path_max_complexity, default_max_allowed_complexity, ) max_complexity = current_max_complexity - blacklisted_vars_amount * complexity_penalty def_line = file_lines[funcdef.lineno - 1] current_complexity = get_node_mccabe_complexity(funcdef) if current_complexity > max_complexity and '# noqa' not in def_line: errors.append((pyfilepath, funcdef.lineno, funcdef.name, current_complexity, max_complexity), ) if errors: for path, line_no, func_name, comlexity, max_comlexity in errors: print( '{0}:{1} {2} is too complex ({3} > {4})'.format( # noqa: T001 path, line_no, func_name, comlexity, max_comlexity, )) return 1