fix: cancel pending futures on SIGINT to prevent traceback on exit (Python 3.13+)#2847
Open
juliosuas wants to merge 12 commits intosherlock-project:masterfrom
Open
fix: cancel pending futures on SIGINT to prevent traceback on exit (Python 3.13+)#2847juliosuas wants to merge 12 commits intosherlock-project:masterfrom
juliosuas wants to merge 12 commits intosherlock-project:masterfrom
Conversation
GNOME VCS (sherlock-project#2804): Switch from response_url to API-based detection using /api/v4/users?username={} endpoint (same approach as GitLab). The previous response_url method failed because non-existent users get 302-redirected to /users/sign_in instead of staying at the profile URL. Patched (sherlock-project#2805): Update domain from patched.sh to patched.to. The site migrated domains, causing all lookups to fail with the old URL. Verified both fixes: GNOME VCS API returns user data for existing users and [] for non-existent ones. Patched.to returns the expected error message for invalid users on the new domain. Fixes sherlock-project#2804 Fixes sherlock-project#2805
Patched.sh now redirects to patched.to, which returns HTTP 403 for all requests (both existing and non-existing users) due to Cloudflare WAF. This causes guaranteed false positives. GNOME VCS fix (API-based detection) is retained and passes F+/F- validation locally.
When the user presses Ctrl-C while Sherlock is scanning, Python's ThreadPoolExecutor (particularly strict in Python 3.13+) prints a noisy traceback during interpreter shutdown because worker threads are still running when sys.exit(0) is called from the signal handler. Fix by: 1. Storing the active SherlockFuturesSession in a module-level variable (_active_session) immediately after it is created inside sherlock(). 2. Calling executor.shutdown(wait=False, cancel_futures=True) from the SIGINT handler before sys.exit(0), so all pending futures are cancelled and the thread pool drains cleanly. The shutdown call is wrapped in a broad except to ensure we never raise inside a signal handler, and the global is set to None initially so the handler is safe to call even before any scan starts. Fixes sherlock-project#2756
Contributor
Automatic validation of changes
|
Author
|
Thanks for the automated validation — Root-Me checks pass on both + and - sides, which confirms the fix doesn't affect detection behavior. To summarize what this PR does: when the user hits Ctrl-C during a scan, Python 3.13+'s Happy to add a test or adjust anything based on your review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #2756 —
Control + Cgenerates a noisy traceback instead of exiting cleanly.Root Cause
When the user presses Ctrl-C, the
handler()function callssys.exit(0). However, there are still worker threads running inside theThreadPoolExecutor(created bySherlockFuturesSession). In Python 3.13+, the interpreter'sthreadingshutdown is stricter and tries to join these threads, which then raiseSystemExitfrom inside a worker — resulting in the exception trace seen in the issue.Fix
_active_sessionvariable that stores a reference to the activeSherlockFuturesSessionimmediately after it is created insidesherlock().handler()to callexecutor.shutdown(wait=False, cancel_futures=True)beforesys.exit(0), so all pending futures are cancelled and the thread pool drains cleanly.exceptto ensure we never raise inside a signal handler.Before
After
Ctrl-C exits immediately and cleanly with no traceback.
Checklist
test_ux.pyunrelated)