Skip to content

fix: disable Rich Live transient mode on Windows to prevent PS 5.1 hang#2938

Open
mnriem wants to merge 3 commits into
mainfrom
mnriem/fix-2927-init-hang-windows
Open

fix: disable Rich Live transient mode on Windows to prevent PS 5.1 hang#2938
mnriem wants to merge 3 commits into
mainfrom
mnriem/fix-2927-init-hang-windows

Conversation

@mnriem

@mnriem mnriem commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #2927specify init hangs indefinitely on Windows PowerShell 5.1 after writing files.

Root Cause

Rich's Live(transient=True) attempts cursor restoration via VT escape sequences when the context manager exits. PowerShell 5.1's legacy console host (conhost.exe) does not reliably support these sequences, causing the cleanup to deadlock.

The hang occurs at line 297 of init.py when the Live block exits — after all files have been written successfully but before "Project ready" prints.

Fix

Set transient=False when sys.platform == "win32" in both locations that use Live(transient=True):

  • src/specify_cli/commands/init.py — progress tracker during scaffolding
  • src/specify_cli/_console.pyselect_with_arrows() interactive menu

The only cosmetic effect is that progress output remains visible after completion on Windows (not erased). No functional impact.

Tests

Added tests/test_live_transient_windows.py with 5 tests:

  • 3 runtime tests that intercept the Live constructor via select_with_arrows() and verify the correct transient kwarg under patched sys.platform (win32, linux, darwin)
  • 2 source-level regression guards verifying both the platform check and transient=_transient usage exist in both files

Copilot AI review requested due to automatic review settings June 11, 2026 13:24
@mnriem mnriem force-pushed the mnriem/fix-2927-init-hang-windows branch from d520ae6 to d3fead3 Compare June 11, 2026 13:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a Windows-specific hang in PowerShell 5.1 by disabling Rich Live(transient=True) cleanup behavior on win32, preventing deadlock during cursor restoration.

Changes:

  • Set transient=False on Windows for the Live progress UI in specify init.
  • Set transient=False on Windows for the Live UI used by _console.select_with_arrows().
  • Add regression tests to confirm the win32 platform guard remains present.
Show a summary per file
File Description
src/specify_cli/commands/init.py Disables Live(transient=True) on Windows during init scaffolding progress rendering.
src/specify_cli/_console.py Disables Live(transient=True) on Windows for the interactive arrow-key selection UI.
tests/test_live_transient_windows.py Adds regression tests covering the Windows transient behavior and guarding against removal of the platform check.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 3/3 changed files
  • Comments generated: 2

Comment thread tests/test_live_transient_windows.py Outdated
Comment thread tests/test_live_transient_windows.py Outdated
Comment thread tests/test_live_transient_windows.py Fixed
Comment thread tests/test_live_transient_windows.py Fixed
Copilot AI review requested due to automatic review settings June 11, 2026 13:40
@mnriem mnriem force-pushed the mnriem/fix-2927-init-hang-windows branch from d3fead3 to f71cb2f Compare June 11, 2026 13:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 2

Comment thread tests/test_live_transient_windows.py Outdated
Comment thread tests/test_live_transient_windows.py Outdated
PowerShell 5.1's legacy console host does not reliably support VT escape
sequences. Rich's Live(transient=True) attempts cursor restoration on
context exit, which hangs indefinitely on that console.

Set transient=False when sys.platform == 'win32' in both init.py (progress
tracker) and _console.py (select_with_arrows). The only cosmetic effect is
that progress output remains visible after completion on Windows.

Fixes #2927

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mnriem mnriem force-pushed the mnriem/fix-2927-init-hang-windows branch from f71cb2f to 984efd8 Compare June 11, 2026 13:56
@mnriem mnriem requested a review from Copilot June 11, 2026 13:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 4

Comment thread tests/test_live_transient_windows.py
Comment thread tests/test_live_transient_windows.py Outdated
Comment thread tests/test_live_transient_windows.py Outdated
Comment thread tests/test_live_transient_windows.py Outdated
- Use captured['transient'] instead of .get() for clearer KeyError on failure
- Source guards now assert both the platform check AND transient=_transient usage
- Remove unused imports (MagicMock retained as it's used, removed pytest)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 2

Comment thread tests/test_live_transient_windows.py Outdated
Comment thread tests/test_live_transient_windows.py
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 1

Comment on lines +75 to +88
init_src = Path(__file__).resolve().parent.parent / "src" / "specify_cli" / "commands" / "init.py"
content = init_src.read_text(encoding="utf-8")
assert re.search(r"sys\.platform\s*!=\s*['\"]win32['\"]", content)
assert re.search(r"transient\s*=\s*_transient", content)

def test_console_has_win32_guard(self):
"""_console.py must check platform and pass transient to Live."""
import re

console_src = Path(__file__).resolve().parent.parent / "src" / "specify_cli" / "_console.py"
content = console_src.read_text(encoding="utf-8")
assert re.search(r"sys\.platform\s*!=\s*['\"]win32['\"]", content)
assert re.search(r"transient\s*=\s*_transient", content)
assert "transient=_transient" in content
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.

specify init hangs on Windows (PowerShell 5.1) after writing files

2 participants