Skip to content

gh-346: Prompt to abort background downloads - #388

Merged
zooba merged 1 commit into
python:mainfrom
Punisheroot:feat/js/prompt-abort-bits-download
Jul 31, 2026
Merged

gh-346: Prompt to abort background downloads#388
zooba merged 1 commit into
python:mainfrom
Punisheroot:feat/js/prompt-abort-bits-download

Conversation

@Punisheroot

Copy link
Copy Markdown
Contributor

Summary

  • Prompt users to abort an active BITS download after pressing Ctrl+C.
  • Cancel the background job automatically when confirmations are disabled with --yes.
  • Preserve the resumable BITS job when the user declines the prompt or cancellation fails.

Context

BITS downloads intentionally continue in the background so that an interrupted installation can reuse the completed download on retry. However, an explicit Ctrl+C indicates that the user may want to stop the background transfer as well.

As discussed in the maintainer's design guidance, an interactive interruption should ask whether to abort the download, while --yes should default to aborting it.

Currently, KeyboardInterrupt leaves _bits_urlretrieve without giving the caller an opportunity to cancel the BITS job.

Closes #346.

Changes

Cancellation prompt

download_package now supplies an optional cancellation callback to urlretrieve. The callback uses the existing cmd.ask_yn(...) confirmation mechanism, so it follows the normal command-line behavior:

  • interactive execution prompts before cancelling;
  • --yes accepts the cancellation without prompting.

BITS interruption handling

When _bits_urlretrieve receives KeyboardInterrupt, it now:

  1. clears the active progress display;
  2. asks whether the background download should be aborted;
  3. cancels the BITS job and removes its .job file when confirmed;
  4. preserves the job and .job file when cancellation is declined;
  5. preserves the .job file and logs a warning if BITS cannot cancel the job;
  6. re-raises KeyboardInterrupt in every case.

Unexpected download errors retain their existing behavior. The WinHTTP, urllib, PowerShell, and local-file download paths are unchanged.

Tests

Added deterministic coverage for:

  • declining cancellation and preserving the resumable job;
  • confirming cancellation and removing the job file;
  • preserving the job file when BITS cancellation fails;
  • resetting the progress display before prompting;
  • treating --yes as confirmation without interactive input.

Validation

Performed on Windows with Python 3.14.6 and pytest 9.1.1:

  • focused new tests: PASS (4 passed);
  • tests/test_urlutils.py and tests/test_install_command.py: PASS (78 passed);
  • git diff --check: PASS.

The BITS interruption tests inject KeyboardInterrupt at the progress polling boundary. A manual interactive Ctrl+C test against a live background download was not performed.

Compatibility and risk

The new on_cancel callback is optional, so existing urlretrieve callers retain their previous behavior. Only the BITS download path consults it after KeyboardInterrupt; normal downloads and fallback selection are unaffected.

The job metadata is removed only after bits_cancel succeeds. This avoids losing the ability to resume a background job when cancellation fails.

@Punisheroot
Punisheroot marked this pull request as ready for review July 31, 2026 10:17
@zooba
zooba merged commit b762348 into python:main Jul 31, 2026
4 checks passed
@zooba

zooba commented Jul 31, 2026

Copy link
Copy Markdown
Member

Thanks! I'm impressed at how you're matching the style of the surrounding code so well, most people (and AIs) don't manage that.

@Punisheroot

Copy link
Copy Markdown
Contributor Author

Thank you! I think I’ve gotten into a bit of a flow state 😄 The context I gained from the previous PR definitely helped ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prompt to abort background downloads on Ctrl + C

2 participants