diff --git a/fimfarchive/converters/alpha_beta/__init__.py b/fimfarchive/converters/alpha_beta/__init__.py index 3f761d6..da19b99 100644 --- a/fimfarchive/converters/alpha_beta/__init__.py +++ b/fimfarchive/converters/alpha_beta/__init__.py @@ -263,7 +263,7 @@ class RootHandler(Handler): return rating and rating.strip().lower() @property - def cover_image(self) -> Dict[str, Any]: + def cover_image(self) -> Optional[Dict[str, Any]]: image = self.meta.get('image') if image is None: @@ -299,7 +299,7 @@ class RootHandler(Handler): return f'
{html.strip()}
' @property - def rating(self) -> int: + def rating(self) -> Optional[int]: likes = self.num_likes dislikes = self.num_dislikes diff --git a/fimfarchive/fetchers/fimfarchive.py b/fimfarchive/fetchers/fimfarchive.py index eab3208..b39c030 100644 --- a/fimfarchive/fetchers/fimfarchive.py +++ b/fimfarchive/fetchers/fimfarchive.py @@ -203,12 +203,15 @@ class FimfarchiveFetcher(Fetcher): def close(self) -> None: self.is_open = False - self.index = None - self.paths = None - if self.archive is not None: + if hasattr(self, 'archive'): self.archive.close() - self.archive = None + + if hasattr(self, 'index'): + self.index.clear() + + if hasattr(self, 'paths'): + self.paths.clear() def fetch_meta(self, key: int) -> Dict[str, Any]: key = self.validate(key) diff --git a/fimfarchive/tasks/update.py b/fimfarchive/tasks/update.py index 084e9d0..95aaa96 100644 --- a/fimfarchive/tasks/update.py +++ b/fimfarchive/tasks/update.py @@ -188,12 +188,15 @@ class UpdateTask(SignalSender): Raises: ValueError: If new story already contains archive meta. """ + if old is None or new is None: + return + try: if 'archive' in new.meta: raise ValueError("New story contains archive meta.") new.meta['archive'] = deepcopy(old.meta['archive']) - except (AttributeError, InvalidStoryError, KeyError): + except (InvalidStoryError, KeyError): return def update(self, key: int) -> Optional[Story]: @@ -213,6 +216,7 @@ class UpdateTask(SignalSender): selected = self.select(old, new) if selected and UpdateStatus.REVIVED in selected.flavors: + assert new is not None selected = selected.merge(meta=new.meta) if selected: diff --git a/tests/fetchers/test_fimfarchive.py b/tests/fetchers/test_fimfarchive.py index bcc5acb..26cfb1f 100644 --- a/tests/fetchers/test_fimfarchive.py +++ b/tests/fetchers/test_fimfarchive.py @@ -31,7 +31,7 @@ from fimfarchive.fetchers import FimfarchiveFetcher VALID_STORY_KEY = 9 INVALID_STORY_KEY = 7 -FIMFARCHIVE_PATH = 'fimfarchive-20171203.zip' +FIMFARCHIVE_PATH = 'fimfarchive.zip' class TestFimfarchiveFetcher: @@ -39,7 +39,7 @@ class TestFimfarchiveFetcher: FimfarchiveFetcher tests. """ - @pytest.yield_fixture(scope='module') + @pytest.fixture(scope='module') def fetcher(self): """ Returns the fetcher instance to test. @@ -84,3 +84,11 @@ class TestFimfarchiveFetcher: """ with pytest.raises(InvalidStoryError): fetcher.fetch_data(INVALID_STORY_KEY) + + @pytest.mark.parametrize('attr', ('archive', 'index', 'paths')) + def test_close_when_missing_attribute(self, attr): + """ + Tests close works even after partial initialization. + """ + with FimfarchiveFetcher(FIMFARCHIVE_PATH) as fetcher: + delattr(fetcher, attr)