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
« 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
5"""Universal report objects and some formatting drivers.
7A way to create simple reports using python objects, primarily designed to be
8formatted as text and html.
9"""
11from __future__ import annotations
13import sys
14from collections.abc import Iterator
15from io import StringIO
16from typing import TYPE_CHECKING, TextIO
18if TYPE_CHECKING:
19 from pylint.reporters.ureports.nodes import (
20 BaseLayout,
21 EvaluationSection,
22 Paragraph,
23 Section,
24 Table,
25 )
28class BaseWriter:
29 """Base class for ureport writers."""
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.
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()
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)
58 def writeln(self, string: str = "") -> None:
59 """Write a line in the output buffer."""
60 self.write(string + "\n")
62 def write(self, string: str) -> None:
63 """Write a string in the output buffer."""
64 self.out.write(string)
66 def begin_format(self) -> None:
67 """Begin to format a layout."""
68 self.section = 0
70 def end_format(self) -> None:
71 """Finished formatting a layout."""
73 def get_table_content(self, table: Table) -> list[list[str]]:
74 """Trick to get table content without actually writing it.
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
90 def compute_content(self, layout: BaseLayout) -> Iterator[str]:
91 """Trick to compute the formatting of children layout before actually
92 writing it.
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