From 948dfa6588052feb5f79a8068c4fb091b2cf25cf Mon Sep 17 00:00:00 2001 From: bonnal-enzo Date: Mon, 4 Dec 2023 11:38:07 +0100 Subject: [PATCH] 0.6.1: move name/descr from Pipes into ExplainingVisitor methods --- kioss/_pipe.py | 45 ++++----------------------- kioss/_visit/_explanation.py | 60 ++++++++++++++++++++++++++---------- setup.py | 2 +- 3 files changed, 51 insertions(+), 56 deletions(-) diff --git a/kioss/_pipe.py b/kioss/_pipe.py index 1f345e6..2f49036 100644 --- a/kioss/_pipe.py +++ b/kioss/_pipe.py @@ -35,7 +35,13 @@ def __iter__(self) -> Iterator[T]: raise ValueError("_pipe.ITERATOR_PRODUCING_VISITOR_CLASS is None") return self._accept(ITERATOR_PRODUCING_VISITOR_CLASS()) + def __add__(self, other: "APipe[T]") -> "APipe[T]": + return self.chain(other) + def __repr__(self) -> str: + """ + Explain the plan of the pipe + """ if EXPLAINING_VISITOR_CLASS is None: raise ValueError("_pipe.EXPLAINING_VISITOR_CLASS is None") return self._accept(EXPLAINING_VISITOR_CLASS()) @@ -44,9 +50,6 @@ def __repr__(self) -> str: def _accept(self, visitor: "AVisitor") -> Any: raise NotImplementedError() - def __add__(self, other: "APipe[T]") -> "APipe[T]": - return self.chain(other) - @staticmethod def sanitize_n_threads(n_threads: int): if not isinstance(n_threads, int): @@ -271,9 +274,6 @@ def __init__(self, source: Callable[[], Iterator[T]]): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_source_pipe(self) - def __str__(self) -> str: - return f"Source(of type: {type(self.source)})" - class FilterPipe(APipe[T]): def __init__(self, upstream: APipe[T], predicate: Callable[[T], bool]): @@ -283,9 +283,6 @@ def __init__(self, upstream: APipe[T], predicate: Callable[[T], bool]): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_filter_pipe(self) - def __str__(self) -> str: - return f"Filter(using predicate function of type {type(self.predicate)})" - class MapPipe(APipe[R]): def __init__(self, upstream: APipe[T], func: Callable[[T], R], n_threads: int): @@ -296,9 +293,6 @@ def __init__(self, upstream: APipe[T], func: Callable[[T], R], n_threads: int): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_map_pipe(self) - def __str__(self) -> str: - return f"Map(function of type {type(self.func)}, using {self.n_threads} thread{'s' if self.n_threads > 1 else ''})" - class DoPipe(APipe[T]): def __init__(self, upstream: APipe[T], func: Callable[[T], R], n_threads: int): @@ -309,9 +303,6 @@ def __init__(self, upstream: APipe[T], func: Callable[[T], R], n_threads: int): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_do_pipe(self) - def __str__(self) -> str: - return f"Do(side effects by applying a function of type {type(self.func)}, using {self.n_threads} thread{'s' if self.n_threads > 1 else ''})" - class LogPipe(APipe[T]): def __init__(self, upstream: APipe[T], what: str = "elements"): @@ -321,9 +312,6 @@ def __init__(self, upstream: APipe[T], what: str = "elements"): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_log_pipe(self) - def __str__(self) -> str: - return f"Log('{self.what}')" - class FlattenPipe(APipe[T]): def __init__(self, upstream: APipe[Iterator[T]], n_threads: int): @@ -333,11 +321,6 @@ def __init__(self, upstream: APipe[Iterator[T]], n_threads: int): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_flatten_pipe(self) - def __str__(self) -> str: - return ( - f"Flatten(using {self.n_threads} thread{'s' if self.n_threads > 1 else ''})" - ) - class BatchPipe(APipe[List[T]]): def __init__(self, upstream: APipe[T], size: int, period: float): @@ -348,9 +331,6 @@ def __init__(self, upstream: APipe[T], size: int, period: float): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_batch_pipe(self) - def __str__(self) -> str: - return f"Batch(elements by groups of {self.size} element{'s' if self.size > 1 else ''}, or over a period of {self.period} second{'s' if self.period > 1 else ''})" - class CatchPipe(APipe[T]): def __init__( @@ -366,9 +346,6 @@ def __init__( def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_catch_pipe(self) - def __str__(self) -> str: - return f"Catch(exception instances of class in [{', '.join(map(lambda class_: class_.__name__, self.classes))}]{', with an additional `when` condition' if self.when is not None else ''})" - class ChainPipe(APipe[T]): def __init__(self, upstream: APipe[T], others: List[APipe]): @@ -378,9 +355,6 @@ def __init__(self, upstream: APipe[T], others: List[APipe]): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_chain_pipe(self) - def __str__(self) -> str: - return f"Chain({len(self.others)+1} pipes)" # TODO itricate explains - class SlowPipe(APipe[T]): def __init__(self, upstream: APipe[T], freq: float): @@ -389,10 +363,3 @@ def __init__(self, upstream: APipe[T], freq: float): def _accept(self, visitor: "AVisitor") -> Any: return visitor.visit_slow_pipe(self) - - def __str__(self) -> str: - return f"Slow(at a maximum frequancy of {self.freq} element{'s' if self.freq > 1 else ''} per second)" - - -# a: Iterator[str] = SourcePipe(range(8).__iter__).do(lambda e:e).map(str).do(print)._accept(ITERATOR_PRODUCING_VISITOR()) -# b: Iterator[str] = SourcePipe(range(8).__iter__).do(lambda e:e).map(str).do(print)._accept(_visitor.IteratorGeneratingVisitor()) diff --git a/kioss/_visit/_explanation.py b/kioss/_visit/_explanation.py index 27e04d4..bf663a3 100644 --- a/kioss/_visit/_explanation.py +++ b/kioss/_visit/_explanation.py @@ -12,17 +12,16 @@ def __init__(self, initial_margin: int = 0, add_header: bool = True): self.margin_step = 2 self.add_header = add_header - def additional_explain_lines(self, pipe: _pipe.APipe) -> str: - name, descr = str(pipe).split("(") - return f"{' '*self.current_margin}{_util.colorize_in_grey('└' + '─'*(self.margin_step - 1))}•{_util.colorize_in_red(name)}({descr}\n" + def additional_explain_lines(self, name: str, descr: str) -> str: + return f"{' '*self.current_margin}{_util.colorize_in_grey('└' + '─'*(self.margin_step - 1))}•{_util.colorize_in_red(name)}({descr})\n" - def visit_any_pipe(self, pipe: _pipe.APipe) -> str: + def visit_any_pipe(self, pipe: _pipe.APipe, name: str, descr: str) -> str: if self.add_header: header = _util.bold(ExplainingVisitor.HEADER) + "\n" self.add_header = False else: header = "" - additional_explain_lines = self.additional_explain_lines(pipe) + additional_explain_lines = self.additional_explain_lines(name, descr) self.current_margin += self.margin_step if pipe.upstream is not None: upstream_repr = pipe.upstream._accept(self) @@ -31,33 +30,62 @@ def visit_any_pipe(self, pipe: _pipe.APipe) -> str: return f"{header}{additional_explain_lines}{upstream_repr}" def visit_chain_pipe(self, pipe: _pipe.ChainPipe) -> Any: - additional_explain_lines = self.additional_explain_lines(pipe) + name = "Chain" + descr = f"{len(pipe.others)+1} pipes" + additional_explain_lines = self.additional_explain_lines(name, descr) self.current_margin += self.margin_step - return f"{additional_explain_lines}{''.join(map(lambda pipe: pipe._accept(ExplainingVisitor(self.current_margin, add_header=False)), pipe.others))}{self.visit_any_pipe(pipe.upstream)}" + chained_pipes_repr = "".join( + map( + lambda pipe: pipe._accept( + ExplainingVisitor(self.current_margin, add_header=False) + ), + pipe.others, + ) + ) + upstream_repr = pipe.upstream._accept(self) + return f"{additional_explain_lines}{chained_pipes_repr}{upstream_repr}" def visit_source_pipe(self, pipe: _pipe.SourcePipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Source" + descr = f"of type: {type(pipe.source)}" + return self.visit_any_pipe(pipe, name, descr) def visit_map_pipe(self, pipe: _pipe.MapPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Map" + descr = f"function of type {type(pipe.func)}, using {pipe.n_threads} thread{'s' if pipe.n_threads > 1 else ''}" + return self.visit_any_pipe(pipe, name, descr) def visit_do_pipe(self, pipe: _pipe.DoPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Do" + descr = f"side effects by applying a function of type {type(pipe.func)}, using {pipe.n_threads} thread{'s' if pipe.n_threads > 1 else ''}" + return self.visit_any_pipe(pipe, name, descr) def visit_flatten_pipe(self, pipe: _pipe.FlattenPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Flatten" + descr = f"using {pipe.n_threads} thread{'s' if pipe.n_threads > 1 else ''}" + return self.visit_any_pipe(pipe, name, descr) def visit_filter_pipe(self, pipe: _pipe.FilterPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Filter" + descr = f"using predicate function of type {type(pipe.predicate)}" + return self.visit_any_pipe(pipe, name, descr) def visit_batch_pipe(self, pipe: _pipe.BatchPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Batch" + descr = f"elements by groups of {pipe.size} element{'s' if pipe.size > 1 else ''}, or over a period of {pipe.period} second{'s' if pipe.period > 1 else ''}" + return self.visit_any_pipe(pipe, name, descr) def visit_slow_pipe(self, pipe: _pipe.SlowPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Slow" + descr = f"at a maximum frequancy of {pipe.freq} element{'s' if pipe.freq > 1 else ''} per second" + return self.visit_any_pipe(pipe, name, descr) def visit_catch_pipe(self, pipe: _pipe.CatchPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Catch" + descr = f"exception instances of class in [{', '.join(map(lambda class_: class_.__name__, pipe.classes))}]{', with an additional `when` condition' if pipe.when is not None else ''}" + return self.visit_any_pipe(pipe, name, descr) def visit_log_pipe(self, pipe: _pipe.LogPipe) -> Any: - return self.visit_any_pipe(pipe) + name = "Log" + descr = f"the evolution of the ieration over {pipe.what}" + return self.visit_any_pipe(pipe, name, descr) diff --git a/setup.py b/setup.py index 65194f3..f97d3c8 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='kioss', - version='0.6.0', + version='0.6.1', packages=['kioss'], url='http://github.com/bonnal-enzo/kioss', license='Apache 2.',