Prints/captures output from the given asynchronous iterable.

    Args:
        async_chunks: An asynchronous source of bytes or str.
        out: Where to put the chunks.

    Returns:
        The complete captured output, or else None if the out argument wasn't a
        TeeCapture instance.

async def _async_forward(async_chunks: collections.AsyncIterable,
                         out: Optional[Union[TeeCapture, IO[str]]]
                         ) -> Optional[str]:
    """Prints/captures output from the given asynchronous iterable.

    Args:
        async_chunks: An asynchronous source of bytes or str.
        out: Where to put the chunks.

    Returns:
        The complete captured output, or else None if the out argument wasn't a
        TeeCapture instance.
    """
    capture = isinstance(out, TeeCapture)
    out_pipe = out.out_pipe if isinstance(out, TeeCapture) else out

    chunks = [] if capture else None  # type: Optional[List[str]]
    async for chunk in async_chunks:
        if not isinstance(chunk, str):
            chunk = chunk.decode()
        if out_pipe:
            print(chunk, file=out_pipe, end='')
        if chunks is not None:
            chunks.append(chunk)

    return ''.join(chunks) if chunks is not None else None