Coverage for src/pytest_vulture/vulture/output_line.py: 0.00%

1"""Manages vulture output lines"""

2 import re

3

4 from pathlib import Path

5 from typing import Optional

6

7

8 class VultureOutputLine:

9 """A vulture output line

10 Examples::

11 >>> manager = VultureOutputLine("src/test.py:2: unused function 'test' (60% confidence)")

12 >>> manager.line_number

13 2

14 >>> manager.message

15 "line 2 : unused function 'test' (60% confidence)"

16 >>> manager.path

17 PosixPath('src/test.py')

18 >>> manager.python_path

19 'src.test:test'

20 >>> manager.type

21 'function'

22 """

23 _message: str

24 _type: str = ""

25 _path: Path

26 _line_number: int = -1

27 _UNUSED_FUNCTION_MESSAGE = "unused function"

28 _python_path: str = ""

29

30 def __init__(self, line: str):

31 splitter = line.split(":")

32 self._path = Path(splitter[0])

33 self._message = splitter[-1]

34 try:

35 self._line_number = int(splitter[1])

36 except (ValueError, IndexError):

37 self._line_number = -1

38

39 @property

40 def type(self) -> str:

41 """get the type : function, attribute, property ...

42 Examples::

43 >>> VultureOutputLine("src/test.py:2: unused function 'test' (60% confidence)").type

44 'function'

45 """

46 if not self._type:

47 elements = re.findall("unused [a-z]*", self._message)

48 if elements:

49 self._type = elements[0].replace("unused ", "")

50 return self._type

51

52 @property

53 def line_number(self) -> Optional[int]:

54 """Get the vulture message line number

55 Examples::

56 >>> VultureOutputLine("src/test.py:5: unused function 'test' (60% confidence)").line_number

57 5

58 """

59 if self._line_number == -1:

60 return None

61 return self._line_number

62

63 @property

64 def message(self) -> str:

65 """Get the vulture message

66 Examples::

67 >>> VultureOutputLine("src/test.py:5: unused function 'test' (60% confidence)").message

68 "line 5 : unused function 'test' (60% confidence)"

69 """

70 if self._line_number == -1:

71 return self._message

72 return f"line {self._line_number} : {self._message}"

73

74 @property

75 def path(self) -> Path:

76 """Get file path of the vulture message

77 Examples::

78 >>> VultureOutputLine("src/test.py:5: unused function 'test' (60% confidence)").path

79 PosixPath('src/test.py')

80 """

81 return self._path

82

83 @property

84 def python_path(self) -> str:

85 """Get the python path of the vulture message :

86 Examples::

87 >>> VultureOutputLine("src/test.py:5: unused function 'test' (60% confidence)").python_path

88 'src.test:test'

89 """

90 if not self._python_path:

91 try:

92 relative_path = self.path.relative_to(Path("").absolute())

93 except ValueError:

94 relative_path = self.path

95

96 self._python_path = relative_path.as_posix().replace("/", ".").replace(".py", "")

97 dots_message = f"{self._UNUSED_FUNCTION_MESSAGE} '"

98 find = re.findall(

99 f"(?={dots_message}).*(?<=')", self._message

100 )

101 if find:

102 function_name = find[0].replace(dots_message, "")

103 self._python_path += ":" + function_name[:-1]

104 return self._python_path

105

106 def __str__(self): # pragma: no cover

107 return self.message