def dataflow_to_dataset(df, types):
        """
        Wrap a dataflow to tf.data.Dataset.
        This function will also reset the dataflow.

        If the dataflow itself is finite, the returned dataset is also finite.
        Therefore, if used for training, you'll need to add `.repeat()` on the returned
        dataset.

        Args:
            df (DataFlow): a dataflow which produces lists
            types([tf.DType]): list of types

        Returns:
            (tf.data.Dataset)

        Note:
            TensorFlow may keep the dataflow alive even if the dataset is no
            longer used.
        """
        # TODO theoretically it can support dict
        assert isinstance(df, DataFlow), df
        assert isinstance(types, (list, tuple)), types
        df = MapData(df, tuple)
        df.reset_state()
        ds = tf.data.Dataset.from_generator(
            df.get_data, tuple(types))
        return ds

        Wrap a dataflow to tf.data.Dataset.
        This function will also reset the dataflow.

        If the dataflow itself is finite, the returned dataset is also finite.
        Therefore, if used for training, you'll need to add `.repeat()` on the returned
        dataset.

        Args:
            df (DataFlow): a dataflow which produces lists
            types([tf.DType]): list of types

        Returns:
            (tf.data.Dataset)

        Note:
            TensorFlow may keep the dataflow alive even if the dataset is no
            longer used.
        
tensorpack/input_source/input_source.py