You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Typed ImageSaveError subclasses: NetworkError, InvalidImageError, DuplicateImageError, WriteError. All
are subclasses of ImageSaveError (so existing except ImageSaveError: continues to work) but give callers
a way to distinguish failure reasons without parsing the reason string. Resolves the 3.2.1 TODO.
on_progress hook on Downloader: on_progress(percent, downloaded, total, eta_seconds). Fires
after each successful download. eta_seconds is None until
the second download (one sample isn't enough to extrapolate).
Powers progress bars and ETA displays.
Downloader.search_async(): async wrapper around search(). Runs the existing engine in a thread via asyncio.to_thread(), so it works with the stdlib-only
urllib-based engines — no new dependencies, no aiohttp. Returns the same Result. Hooks, cancellation
token, and progress callback all work.
ImageSaveError and subclasses are now exposed at the top
level (from better_bing_image_downloader import NetworkError, etc.).
_save_image_raising() method on ImageEngine — the
new typed-exception variant. save_image() is now a thin
wrapper that catches and returns False for backwards
compatibility. Downloader.search uses the raising variant
directly.
Changed
save_image is now the catching wrapper. Existing code that
calls engine.save_image() and checks the bool return value
continues to work unchanged. New code that wants typed
exceptions should use engine._save_image_raising().
Result.errors entries that come from a save_image
failure are now typed (e.g. NetworkError instead of
generic ImageSaveError(reason="save_failed")). Users
catching ImageSaveError are unaffected.
Tests
11 new tests in tests/test_v3_4_0_features.py:
ImageSaveError subclass importability and Liskov
substitution