Source code for lena.core.sequence

"""Sequence class."""
from __future__ import print_function

import sys

from . import lena_sequence
from . import adapters
from . import exceptions
from . import functions


[docs]class Sequence(lena_sequence.LenaSequence): """Sequence of elements, such that next takes input from the previous during *run*. :meth:`Sequence.run` must accept input flow. For sequence with no input data use :class:`Source`. """ def __init__(self, *args): """*args* are objects which implement a method *run(flow)* or callables. *args* can be a single tuple of such elements. In this case one doesn't need to check argument type when initializing a Sequence in a general function. For more information about the *run* method and callables, see :class:`Run`. """ self._seq = [] # Sequence can be initialized from a single tuple if len(args) == 1 and isinstance(args[0], tuple): args = args[0] for elem in args: run = getattr(elem, "run", None) if callable(run): self._seq.append(elem) else: try: run_elem = adapters.Run(elem) except exceptions.LenaTypeError: raise exceptions.LenaTypeError( "arguments must implement run method, " "or be callable generators (convertible to Run), " "{} given".format(elem) ) else: self._seq.append(run_elem) # we don't call super init (yet), # because it has no variables (and no init) # https://softwareengineering.stackexchange.com/a/318171/42050
[docs] def run(self, flow): """Generator, which transforms the incoming flow. If this :class:`Sequence` is empty, the flow passes untransformed, with a small change. This function converts input flow to an iterator, so that it always contains both *iter* and *next* methods. This is done for the flow entering the first sequence element and exiting from the sequence. """ flow = functions.flow_to_iter(flow) for elem in self._seq: flow = elem.run(flow) flow = functions.flow_to_iter(flow) # This function is not a generator, but returns a generator. # The difference is very subtle. # Most important is that the function is evaluated immediately, # and raises in case of errors. return flow