Summary
Several areas of the codebase can benefit from improved type safety and robustness.
Items
1. Type-safe `_retry_request`
In genius/client.py, _retry_request accepts request_fn as Any and returns Any. This should use generics:
```python
from typing import TypeVar, Callable
T = TypeVar("T")
def _retry_request(self, request_fn: Callable[[], T], retries: int | None = None) -> T:
```
2. Cache race condition handling
cache.py uses file I/O for get_lyrics() and store_lyrics(). If lyrics fetching is parallelized, concurrent access to the same song's cache file could cause race conditions.
Proposed fix: Use atomic writes (write to temp file then rename) or adopt the filelock library.
3. Simplify `_get_cache_path` hashing
cache.py uses hashlib.md5(str(song_id).encode()).hexdigest()[:2] for directory distribution, but since song_id is an integer, a simple song_id % 256 would suffice without the MD5 overhead.
Affected Files
src/barscan/genius/client.py
src/barscan/genius/cache.py
Summary
Several areas of the codebase can benefit from improved type safety and robustness.
Items
1. Type-safe `_retry_request`
In
genius/client.py,_retry_requestacceptsrequest_fnasAnyand returnsAny. This should use generics:```python
from typing import TypeVar, Callable
T = TypeVar("T")
def _retry_request(self, request_fn: Callable[[], T], retries: int | None = None) -> T:
```
2. Cache race condition handling
cache.pyuses file I/O forget_lyrics()andstore_lyrics(). If lyrics fetching is parallelized, concurrent access to the same song's cache file could cause race conditions.Proposed fix: Use atomic writes (write to temp file then rename) or adopt the
filelocklibrary.3. Simplify `_get_cache_path` hashing
cache.pyuseshashlib.md5(str(song_id).encode()).hexdigest()[:2]for directory distribution, but sincesong_idis an integer, a simplesong_id % 256would suffice without the MD5 overhead.Affected Files
src/barscan/genius/client.pysrc/barscan/genius/cache.py