diff --git a/fimfarchive/fetchers/directory.py b/fimfarchive/fetchers/directory.py index 3c45a07..025f009 100644 --- a/fimfarchive/fetchers/directory.py +++ b/fimfarchive/fetchers/directory.py @@ -62,6 +62,7 @@ class DirectoryFetcher(Fetcher): """ self.meta_path = meta_path self.data_path = data_path + self.length: Optional[int] = None self.flavors = frozenset(flavors) def iter_path_keys(self, path: Optional[Path]) -> Iterator[int]: @@ -111,7 +112,10 @@ class DirectoryFetcher(Fetcher): """ Returns the total number of stories in the directories. """ - return len(self.list_keys()) + if self.length is None: + self.length = len(self.list_keys()) + + return self.length def __iter__(self) -> Iterator[Story]: """ diff --git a/tests/fetchers/test_directory.py b/tests/fetchers/test_directory.py index 1adae78..d886f78 100644 --- a/tests/fetchers/test_directory.py +++ b/tests/fetchers/test_directory.py @@ -26,6 +26,7 @@ import json import pytest from pathlib import Path from typing import Any, Dict +from unittest.mock import patch from fimfarchive.exceptions import InvalidStoryError from fimfarchive.fetchers import DirectoryFetcher @@ -155,6 +156,15 @@ class TestDirectoryFetcher: """ assert 3 == len(fetcher) + def test_len_caching(test, fetcher): + """ + Tests len is only calculated once. + """ + with patch.object(fetcher, 'list_keys', wraps=fetcher.list_keys) as m: + assert 3 == len(fetcher) + assert 3 == len(fetcher) + assert 1 == len(m.mock_calls) + def test_iter(self, fetcher): """ Tests iter yields all available stories, ordered by key.