| 1667 | frames contain large objects. |
| 1668 | """ |
| 1669 | def __init__(self, fig, func, frames=None, init_func=None, fargs=None, |
| 1670 | save_count=None, *, cache_frame_data=True, **kwargs): |
| 1671 | if fargs: |
| 1672 | self._args = fargs |
| 1673 | else: |
| 1674 | self._args = () |
| 1675 | self._func = func |
| 1676 | self._init_func = init_func |
| 1677 | |
| 1678 | # Amount of framedata to keep around for saving movies. This is only |
| 1679 | # used if we don't know how many frames there will be: in the case |
| 1680 | # of no generator or in the case of a callable. |
| 1681 | self._save_count = save_count |
| 1682 | # Set up a function that creates a new iterable when needed. If nothing |
| 1683 | # is passed in for frames, just use itertools.count, which will just |
| 1684 | # keep counting from 0. A callable passed in for frames is assumed to |
| 1685 | # be a generator. An iterable will be used as is, and anything else |
| 1686 | # will be treated as a number of frames. |
| 1687 | if frames is None: |
| 1688 | self._iter_gen = itertools.count |
| 1689 | elif callable(frames): |
| 1690 | self._iter_gen = frames |
| 1691 | elif np.iterable(frames): |
| 1692 | if kwargs.get('repeat', True): |
| 1693 | self._tee_from = frames |
| 1694 | def iter_frames(frames=frames): |
| 1695 | this, self._tee_from = itertools.tee(self._tee_from, 2) |
| 1696 | yield from this |
| 1697 | self._iter_gen = iter_frames |
| 1698 | else: |
| 1699 | self._iter_gen = lambda: iter(frames) |
| 1700 | if hasattr(frames, '__len__'): |
| 1701 | self._save_count = len(frames) |
| 1702 | if save_count is not None: |
| 1703 | _api.warn_external( |
| 1704 | f"You passed in an explicit {save_count=} " |
| 1705 | "which is being ignored in favor of " |
| 1706 | f"{len(frames)=}." |
| 1707 | ) |
| 1708 | else: |
| 1709 | self._iter_gen = lambda: iter(range(frames)) |
| 1710 | self._save_count = frames |
| 1711 | if save_count is not None: |
| 1712 | _api.warn_external( |
| 1713 | f"You passed in an explicit {save_count=} which is being " |
| 1714 | f"ignored in favor of {frames=}." |
| 1715 | ) |
| 1716 | if self._save_count is None and cache_frame_data: |
| 1717 | _api.warn_external( |
| 1718 | f"{frames=!r} which we can infer the length of, " |
| 1719 | "did not pass an explicit *save_count* " |
| 1720 | f"and passed {cache_frame_data=}. To avoid a possibly " |
| 1721 | "unbounded cache, frame data caching has been disabled. " |
| 1722 | "To suppress this warning either pass " |
| 1723 | "`cache_frame_data=False` or `save_count=MAX_FRAMES`." |
| 1724 | ) |
| 1725 | cache_frame_data = False |
| 1726 | |