Coverage for C:\Repos\ekr-pylint\pylint\reporters\ureports\base_writer.py: 34%

47 statements  

« prev     ^ index     » next       coverage.py v6.4, created at 2022-05-24 10:21 -0500

1# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html 

2# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE 

3# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt 

4 

5"""Universal report objects and some formatting drivers. 

6 

7A way to create simple reports using python objects, primarily designed to be 

8formatted as text and html. 

9""" 

10 

11from __future__ import annotations 

12 

13import sys 

14from collections.abc import Iterator 

15from io import StringIO 

16from typing import TYPE_CHECKING, TextIO 

17 

18if TYPE_CHECKING: 

19 from pylint.reporters.ureports.nodes import ( 

20 BaseLayout, 

21 EvaluationSection, 

22 Paragraph, 

23 Section, 

24 Table, 

25 ) 

26 

27 

28class BaseWriter: 

29 """Base class for ureport writers.""" 

30 

31 def format( 

32 self, 

33 layout: BaseLayout, 

34 stream: TextIO = sys.stdout, 

35 encoding: str | None = None, 

36 ) -> None: 

37 """Format and write the given layout into the stream object. 

38 

39 unicode policy: unicode strings may be found in the layout; 

40 try to call 'stream.write' with it, but give it back encoded using 

41 the given encoding if it fails 

42 """ 

43 if not encoding: 

44 encoding = getattr(stream, "encoding", "UTF-8") 

45 self.encoding = encoding or "UTF-8" 

46 self.out = stream 

47 self.begin_format() 

48 layout.accept(self) 

49 self.end_format() 

50 

51 def format_children(self, layout: EvaluationSection | Paragraph | Section) -> None: 

52 """Recurse on the layout children and call their accept method 

53 (see the Visitor pattern). 

54 """ 

55 for child in getattr(layout, "children", ()): 

56 child.accept(self) 

57 

58 def writeln(self, string: str = "") -> None: 

59 """Write a line in the output buffer.""" 

60 self.write(string + "\n") 

61 

62 def write(self, string: str) -> None: 

63 """Write a string in the output buffer.""" 

64 self.out.write(string) 

65 

66 def begin_format(self) -> None: 

67 """Begin to format a layout.""" 

68 self.section = 0 

69 

70 def end_format(self) -> None: 

71 """Finished formatting a layout.""" 

72 

73 def get_table_content(self, table: Table) -> list[list[str]]: 

74 """Trick to get table content without actually writing it. 

75 

76 return an aligned list of lists containing table cells values as string 

77 """ 

78 result: list[list[str]] = [[]] 

79 cols = table.cols 

80 for cell in self.compute_content(table): 

81 if cols == 0: 

82 result.append([]) 

83 cols = table.cols 

84 cols -= 1 

85 result[-1].append(cell) 

86 # fill missing cells 

87 result[-1] += [""] * (cols - len(result[-1])) 

88 return result 

89 

90 def compute_content(self, layout: BaseLayout) -> Iterator[str]: 

91 """Trick to compute the formatting of children layout before actually 

92 writing it. 

93 

94 return an iterator on strings (one for each child element) 

95 """ 

96 # Patch the underlying output stream with a fresh-generated stream, 

97 # which is used to store a temporary representation of a child 

98 # node. 

99 out = self.out 

100 try: 

101 for child in layout.children: 

102 stream = StringIO() 

103 self.out = stream 

104 child.accept(self) 

105 yield stream.getvalue() 

106 finally: 

107 self.out = out