Coverage for tsfpga/test/lint/python_lint.py: 69%

36 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-07 20:51 +0000

1# -------------------------------------------------------------------------------------------------- 

2# Copyright (c) Lukas Vik. All rights reserved. 

3# 

4# This file is part of the tsfpga project, a project platform for modern FPGA development. 

5# https://tsfpga.com 

6# https://github.com/tsfpga/tsfpga 

7# -------------------------------------------------------------------------------------------------- 

8# Reusable code for Python linting. 

9# -------------------------------------------------------------------------------------------------- 

10 

11# Standard libraries 

12import subprocess 

13import sys 

14from pathlib import Path 

15 

16# Third party libraries 

17import pytest 

18 

19# First party libraries 

20import tsfpga 

21from tsfpga.system_utils import create_file, run_command 

22 

23THIS_DIR = Path(__file__).parent.resolve() 

24 

25 

26def run_pylint(files: list[Path]) -> None: 

27 """ 

28 Will raise exception if any of the ``files`` does not pass the 'pylint' lint check. 

29 """ 

30 command = [sys.executable, "-m", "pylint", "--rcfile", str(THIS_DIR / "pylintrc")] + [ 

31 str(file_path) for file_path in files 

32 ] 

33 

34 run_command(command) 

35 

36 

37def run_black(files: list[Path]) -> None: 

38 """ 

39 Will raise exception if any of the ``files`` does not pass the 'black' formatting check. 

40 """ 

41 command = [sys.executable, "-m", "black", "--check", "--diff"] + [ 

42 str(file_path) for file_path in files 

43 ] 

44 run_command(command) 

45 

46 

47def run_isort(files: list[Path], cwd: Path) -> None: 

48 """ 

49 Run the 'isort' Python tool. 

50 Will raise exception if any of the ``files`` does not pass the check. 

51 

52 Arguments: 

53 files: The files that shall be checked. 

54 cwd: Path where the command shall be executed. 

55 The ``pyproject.toml`` file should be located here. 

56 """ 

57 command = [sys.executable, "-m", "isort", "--check", "--diff"] + [ 

58 str(file_path) for file_path in files 

59 ] 

60 run_command(command, cwd=cwd) 

61 

62 

63def run_flake8_lint(files: list[Path]) -> None: 

64 """ 

65 Will raise exception if any of the ``files`` does not pass the 'flake8' lint check. 

66 """ 

67 command = [sys.executable, "-m", "flake8"] + [str(file_path) for file_path in files] 

68 run_command(command, cwd=tsfpga.REPO_ROOT) 

69 

70 

71# pylint: disable=redefined-outer-name 

72@pytest.fixture 

73def invalid_python_code_file(tmp_path: Path) -> Path: 

74 ugly_code = "aa =\ndef bb:\ncc = 3" 

75 return create_file(tmp_path / "dummy_python_file.py", ugly_code) 

76 

77 

78def test_pylint_should_raise_exception_if_there_are_ugly_files( 

79 invalid_python_code_file: Path, 

80) -> None: 

81 with pytest.raises(subprocess.CalledProcessError): 

82 run_pylint(files=[invalid_python_code_file]) 

83 

84 

85def test_flake8_lint_should_raise_exception_if_there_are_ugly_files( 

86 invalid_python_code_file: Path, 

87) -> None: 

88 with pytest.raises(subprocess.CalledProcessError): 

89 run_flake8_lint(files=[invalid_python_code_file]) 

90 

91 

92def test_black_formatting_should_raise_exception_if_there_are_ugly_files( 

93 invalid_python_code_file: Path, 

94) -> None: 

95 with pytest.raises(subprocess.CalledProcessError): 

96 run_black(files=[invalid_python_code_file]) 

97 

98 

99def test_isort_formatting_should_raise_exception_if_there_are_ugly_files(tmp_path: Path) -> None: 

100 file_path = create_file( 

101 file=tmp_path / "dummy_python_file.py", 

102 contents=""" 

103import b 

104import a 

105 

106""", 

107 ) 

108 

109 with pytest.raises(subprocess.CalledProcessError): 

110 run_isort(files=[file_path], cwd=tsfpga.REPO_ROOT)