<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _next_batch(self) -> Optional[Batch]: """ Return a single batch or ``None`` signaling epoch end. .. note:: Signal the epoch end with ``None``. Stop when: - stream ends and epoch size is not set - specified number of batches is returned :return: a single batch or ``None`` signaling epoch end """

        if self._epoch_limit_reached():
            self._batch_count = 0
            return None
        try:
            batch = next(self._get_stream())
            self._batch_count += 1
            return batch
        except StopIteration:
            self._stream = None  # yield a new iterator next time
            if self._epoch_size > 0:  # underlying stream ended but our fixed size epoch did not
                batch = next(self._get_stream())  # get another stream and return its 1st batch
                self._batch_count += 1
                return batch
            else:
                self._batch_count = 0
                return None