diff options
Diffstat (limited to 'logilab/common/ureports/__init__.py')
-rw-r--r-- | logilab/common/ureports/__init__.py | 83 |
1 files changed, 60 insertions, 23 deletions
diff --git a/logilab/common/ureports/__init__.py b/logilab/common/ureports/__init__.py index 8ce68a0..9c0f1df 100644 --- a/logilab/common/ureports/__init__.py +++ b/logilab/common/ureports/__init__.py @@ -26,6 +26,9 @@ import sys from logilab.common.compat import StringIO from logilab.common.textutils import linesep +from logilab.common.tree import VNode +from logilab.common.ureports.nodes import Table, List as NodeList +from typing import Any, Optional, Union, List, Generator, Tuple, Callable, TextIO def get_nodes(node, klass): @@ -76,7 +79,7 @@ def build_summary(layout, level=1): class BaseWriter(object): """base class for ureport writers""" - def format(self, layout, stream=None, encoding=None): + def format(self, layout: Any, stream: Optional[Union[StringIO, TextIO]] = None, encoding: Optional[Any] = None) -> None: """format and write the given layout into the stream object unicode policy: unicode strings may be found in the layout; @@ -88,87 +91,121 @@ class BaseWriter(object): if not encoding: encoding = getattr(stream, 'encoding', 'UTF-8') self.encoding = encoding or 'UTF-8' - self.__compute_funcs = [] + self.__compute_funcs: List[Tuple[Callable[[str], Any], Callable[[str], Any]]] = [] self.out = stream self.begin_format(layout) layout.accept(self) self.end_format(layout) - def format_children(self, layout): + def format_children(self, layout: Union['Paragraph', 'Section', 'Title']) -> None: """recurse on the layout children and call their accept method (see the Visitor pattern) """ for child in getattr(layout, 'children', ()): child.accept(self) - def writeln(self, string=u''): + def writeln(self, string: str = u'') -> None: """write a line in the output buffer""" self.write(string + linesep) - def write(self, string): + def write(self, string: str) -> None: """write a string in the output buffer""" try: self.out.write(string) except UnicodeEncodeError: - self.out.write(string.encode(self.encoding)) + # mypy: Argument 1 to "write" of "IO" has incompatible type "bytes"; expected "str" + # probably a python3 port issue? + self.out.write(string.encode(self.encoding)) # type: ignore - def begin_format(self, layout): + def begin_format(self, layout: Any) -> None: """begin to format a layout""" self.section = 0 - def end_format(self, layout): + def end_format(self, layout: Any) -> None: """finished to format a layout""" - def get_table_content(self, table): + def get_table_content(self, table: Table) -> List[List[str]]: """trick to get table content without actually writing it return an aligned list of lists containing table cells values as string """ - result = [[]] - cols = table.cols + result: List[List[str]] = [[]] + # mypy: "Table" has no attribute "cols" + # dynamic attribute + cols = table.cols # type: ignore + for cell in self.compute_content(table): if cols == 0: result.append([]) - cols = table.cols + # mypy: "Table" has no attribute "cols" + # dynamic attribute + cols = table.cols # type: ignore + cols -= 1 result[-1].append(cell) + # fill missing cells while len(result[-1]) < cols: result[-1].append(u'') + return result - def compute_content(self, layout): + def compute_content(self, layout: VNode) -> Generator[str, Any, None]: """trick to compute the formatting of children layout before actually writing it return an iterator on strings (one for each child element) """ # use cells ! - def write(data): + def write(data: str) -> None: try: stream.write(data) except UnicodeEncodeError: - stream.write(data.encode(self.encoding)) - def writeln(data=u''): + # mypy: Argument 1 to "write" of "TextIOWrapper" has incompatible type "bytes"; + # mypy: expected "str" + # error from porting to python3? + stream.write(data.encode(self.encoding)) # type: ignore + + def writeln(data: str = u'') -> None: try: stream.write(data+linesep) except UnicodeEncodeError: - stream.write(data.encode(self.encoding)+linesep) - self.write = write - self.writeln = writeln + # mypy: Unsupported operand types for + ("bytes" and "str") + # error from porting to python3? + stream.write(data.encode(self.encoding)+linesep) # type: ignore + + # mypy: Cannot assign to a method + # this really looks like black dirty magic since self.write is reused elsewhere in the code + # especially since self.write and self.writeln are conditionally + # deleted at the end of this function + self.write = write # type: ignore + self.writeln = writeln # type: ignore + self.__compute_funcs.append((write, writeln)) - for child in layout.children: + + # mypy: Item "Table" of "Union[List[Any], Table, Title]" has no attribute "children" + # dynamic attribute? + for child in layout.children: # type: ignore stream = StringIO() + child.accept(self) + yield stream.getvalue() + self.__compute_funcs.pop() + try: - self.write, self.writeln = self.__compute_funcs[-1] + # mypy: Cannot assign to a method + # even more black dirty magic + self.write, self.writeln = self.__compute_funcs[-1] # type: ignore except IndexError: del self.write del self.writeln - -from logilab.common.ureports.nodes import * +# mypy error: Incompatible import of "Table" (imported name has type +# mypy error: "Type[logilab.common.ureports.nodes.Table]", local name has type +# mypy error: "Type[logilab.common.table.Table]") +# this will be cleaned when the "*" will be removed +from logilab.common.ureports.nodes import * # type: ignore from logilab.common.ureports.text_writer import TextWriter from logilab.common.ureports.html_writer import HTMLWriter |