TST: Surface worker thread exceptions in download_test_pdfs#3766
TST: Surface worker thread exceptions in download_test_pdfs#3766jonasboos wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the test infrastructure helper download_test_pdfs() to ensure exceptions raised in worker threads during concurrent PDF downloads are not silently swallowed, making download failures visible at their source instead of later as misleading FileNotFoundErrors.
Changes:
- Replace
concurrent.futures.wait(futures)with iteration overconcurrent.futures.as_completed(futures). - Call
.result()on each completed future to re-raise worker-thread exceptions in the main thread.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| executor.submit(get_data_from_url, url=pdf["url"], name=pdf["local_filename"]) | ||
| for pdf in pdfs | ||
| ] | ||
| concurrent.futures.wait(futures) | ||
| for future in concurrent.futures.as_completed(futures): | ||
| future.result() # re-raises any exception from the worker thread |
Previously, `download_test_pdfs()` called `concurrent.futures.wait(futures)` but never iterated the returned futures or called `.result()` on them. Any exception raised in a worker thread was silently captured, causing confusing downstream FileNotFoundError when tests tried to open missing files. Replace `wait()` with `as_completed()` + `.result()` so that download failures are surfaced immediately at the source. Also fix a race condition this exposed: multiple threads could race on `cache_dir.mkdir()`, raising `FileExistsError` when the directory was created by another thread between the `exists()` check and the `mkdir()` call. Use `mkdir(exist_ok=True)` instead of the check-then-create pattern. Closes py-pdf#3728
8fca0d2 to
94e0853
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3766 +/- ##
=======================================
Coverage 97.62% 97.62%
=======================================
Files 55 55
Lines 10221 10221
Branches 1876 1876
=======================================
Hits 9978 9978
Misses 138 138
Partials 105 105 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
stefan6419846
left a comment
There was a problem hiding this comment.
Thanks for the PR. I have left some comment for a change which seems to be unrelated and not required here before we can continue with this.
| cache_dir = Path(__file__).parent / "pdf_cache" | ||
| if not cache_dir.exists(): | ||
| cache_dir.mkdir() | ||
| cache_dir.mkdir(exist_ok=True) |
There was a problem hiding this comment.
Which benefits does this have?
Summary
Previously,
download_test_pdfs()calledconcurrent.futures.wait(futures)but never iterated the returned futures or called.result()on them. Any exception raised in a worker thread was silently captured, causing confusing downstreamFileNotFoundErrors when tests tried to open missing files.Replace
wait()withas_completed()+.result()so that download failures are surfaced immediately at the source.Fix
concurrent.futures.wait(futures)withconcurrent.futures.as_completed(futures)and call.result()on each future to re-raise any worker thread exceptions.Testing
example_files.yamland confirm thatdownload_test_pdfs()now raises instead of silently swallowing the error.Closes #3728