def flatten(dag, currentAttrs=None, useColors=True):
    # XXX TODO: Add unicode handling!
    """
    Serialize a tree of strings and terminal codes to an iterable of strings,
    ready to be written to your favorite terminal device.

    @type currentAttrs: L{AttributeSet}
    @param currentAttrs: The current set of attributes.

    @param useColors: If False, terminal codes will be left out.
    """
    if currentAttrs is None:
        if not useColors:
            currentAttrs = AttributeSet()
        else:
            raise TypeError("currentAttrs is required when useColors is False")
    attrs = AttributeStack(currentAttrs)
    attrs.duptop()

    stack = [iter(dag)]
    dirty = False
    while stack:
        try:
            obj = stack[-1].next()
        except StopIteration:
            stack.pop()
            attrs.pop()
            if len(attrs):
                if useColors:
                    dirty = bool(attrs.get().toVT102(currentAttrs))
        else:
            if isinstance(obj, AttributeSet):
                attrs.update(obj)
                if useColors:
                    dirty = bool(attrs.get().toVT102(currentAttrs))
            elif isinstance(obj, (str, unicode)):
                if obj:
                    if dirty:
                        if useColors:
                            yield attrs.get().toVT102(currentAttrs)
                        currentAttrs = attrs.get().clone()
                        dirty = False
                    yield obj
            else:
                try:
                    newIter = iter(obj)
                except __HOLE__:
                    if dirty:
                        if useColors:
                            yield attrs.get().toVT102(currentAttrs)
                        currentAttrs = attrs.get().clone()
                        dirty = False
                    yield obj
                else:
                    stack.append(newIter)
                    attrs.duptop()
    if dirty and len(attrs):
        if useColors:
            yield attrs.get().toVT102(currentAttrs)
dataset/ETHPy150Open twisted/imaginary/imaginary/text.py/flatten