Retry copying a file while its source is briefly in use - #20635
Draft
yasumorishima wants to merge 1 commit into
Draft
Retry copying a file while its source is briefly in use#20635yasumorishima wants to merge 1 commit into
yasumorishima wants to merge 1 commit into
Conversation
tryCopyFile raised as soon as CopyFile failed and no destination file had been created, which aborts the whole operation it belongs to. Copying the user configuration to the system configuration walks every file, so a single source file which another process still holds open, such as a database left open while leaving the UAC screen, fails the entire copy and the user is told their settings could not be copied. Retry that case before giving up, mirroring tryRemoveFile, which already retries six times at half second intervals. Failing to overwrite an existing destination file is unchanged and still goes straight to replacing it.
Member
|
I understand that the original issue is hard to reproduce consistently, but have you tested the "happy path" i.e. have you tested copying the files successfully using your new code? |
Member
|
Have you tried reproducing by opening a file with notepad or similar? |
seanbudd
marked this pull request as draft
August 13, 2026 00:21
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.
Link to issue number:
Fixes #20118
Summary of the issue:
Copying the current user configuration to the system configuration, so that it is used on the sign-in and other secure screens, fails with "cannot copy NVDA user settings" while some files are copied and others are not.
config._setSystemConfigwalks the user configuration and callsinstaller.tryCopyFilefor every file.tryCopyFileraises as soon asCopyFilefails and no destination file was created, so a single source file that another process still holds open aborts the whole copy.In the report, a database in the user configuration was still open while NVDA was leaving the UAC screen, which matches @seanbudd's reading of the cause in the issue.
Description of user facing changes:
Copying the configuration to the system configuration no longer fails because a file was briefly in use.
Description of developer facing changes:
installer.tryCopyFiletakes two new optional arguments,numRetries(default 6) andretryInterval(default 0.5). Existing callers are unaffected.Description of development approach:
tryRemoveFilein the same module already retries six times at half second intervals, sotryCopyFilenow follows that pattern rather than introducing a new one.The retry applies only when the copy failed and no destination file exists, which is the case where the source could not be read. When the destination does exist the copy failed while overwriting it, and that path is unchanged: the existing file is still scheduled for deletion and the copy is attempted once more.
Testing strategy:
Unit tests in
tests/unit/test_installer.pycover four cases: success without retrying, retry until success, the configuredretryIntervalbeing used for each wait, and failure once the retries are exhausted.CopyFileandtime.sleepare patched, so the tests assert the retry behaviour rather than filesystem timing.CI on my fork is green, including the installer system tests, which exercise
tryCopyFilethroughcopyProgramFilesduring a real installation.I have not reproduced the original failure, since it depends on another process holding a configuration file open at the moment the copy runs. The change is therefore verified as retry behaviour rather than as a fix confirmed against the reported reproduction.
Known issues with pull request:
@CyrilleB79 noted in the issue that it would be useful to tell the user which files could not be copied. That changes what the user is told rather than whether the copy succeeds, so it is not part of this change.
Code Review Checklist: