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
Beispiel #2
0
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
Beispiel #4
0
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 find_too_long_py_files(allowed_amount: int, filenames: List[str]) -> DefaultDict[str, int]:
    too_long_files: DefaultDict[str, int] = collections.defaultdict(int)
    for py_file_name in get_input_files(filenames):
        amount_of_lines = count_amount_of_lines_in_file(filepath=py_file_name)
        if amount_of_lines <= allowed_amount:
            continue
        too_long_files[py_file_name] = amount_of_lines

    return too_long_files
Beispiel #6
0
def main() -> int:
    has_errors = False

    for pyfilepath in get_input_files():
        for error_message in get_file_errors(
                pyfilepath,
                max_expression_complexity=9,
                ignore_django_orm_queries=True,
        ):
            has_errors = True
            print(error_message)  # noqa: T001

    return int(has_errors)
def main() -> Optional[int]:
    forbidden_imports = get_list_param_from_config('setup.cfg', 'project_structure', 'forbidden_imports')
    if not forbidden_imports:
        return None

    errors: List[str] = []

    for pyfilepath in get_input_files():
        ast_tree: Optional[ast.Module] = get_ast_tree(pyfilepath)
        if ast_tree is None:
            continue

        errors += get_import_errors_in_ast_tree(pyfilepath, ast_tree, forbidden_imports)

    for error in errors:
        print(error)  # noqa: T001
    if errors:
        return 1
Beispiel #8
0
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
Beispiel #9
0
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]:
    exit_zero = True
    module_validators: List[Callable[[str, str, List[str]], List[str]]] = [
        has_only_models_in_models_submodule,
        all_enums_in_enums_py_module,
        has_no_submodules_with_blacklisted_suffixes,
        has_no_empty_py_files,
        views_py_has_only_class_views,
        urls_py_has_urlpatterns,
        no_url_calls,
    ]
    errors: List[str] = []
    for module_name, module_path, module_files in get_modules_files(
            get_input_files(dirs_to_exclude=[])):
        for validator in module_validators:
            errors += validator(module_name, module_path, module_files)

    for error in errors:
        print(error)  # noqa: T001
    if errors and not exit_zero:
        return 1
Beispiel #11
0
def iterate_api_files() -> typing.Iterator[str]:
    return (filepath for filepath in get_input_files()
            if is_api_filepath(filepath)
            and is_serializer_or_view_filepath(filepath))
def main() -> int:
    errors = validate(get_input_files())
    return 1 if errors else 0
Beispiel #13
0
def get_input_models_files(
        args: typing.List[str] = None,
        dirs_to_exclude: typing.List[str] = None) -> typing.Iterator[str]:
    return (filepath
            for filepath in get_input_files(args, dirs_to_exclude, 'py')
            if filepath.endswith('/models.py') or '/models/' in filepath)
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