Read data files and update a generator.

    Parameters
    ----------
    fnames : `list` of `str`
        File paths.
    markov : `markovchain.base.MarkovBase`
        Generator to update.
    progress : `bool`
        Show progress bar.
    leave : `bool`, optional
        Leave progress bars (default: `True`).

def read(fnames, markov, progress, leave=True):
    """Read data files and update a generator.

    Parameters
    ----------
    fnames : `list` of `str`
        File paths.
    markov : `markovchain.base.MarkovBase`
        Generator to update.
    progress : `bool`
        Show progress bar.
    leave : `bool`, optional
        Leave progress bars (default: `True`).
    """
    pbar = None
    channels = markov.imgtype.channels

    tr = markov.scanner.traversal
    if progress and not isinstance(tr[0], TraversalProgressWrapper):
        tr[0] = TraversalProgressWrapper(tr[0], channels)
    tr = tr[0]

    try:
        with infiles(fnames, progress, leave) as fnames:
            for fname in fnames:
                if progress:
                    title = truncate(fname, BAR_DESC_SIZE - 1, False)
                    pbar = tqdm(
                        total=markov.levels * len(channels),
                        desc=title, leave=False, unit='lvl',
                        bar_format=BAR_FORMAT, dynamic_ncols=True
                    )
                    tr.pbar_parent = pbar
                markov.data(Image.open(fname), False)
                if progress:
                    pbar.close()
    finally:
        if pbar is not None:
            pbar.close()