Skip to content

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

Open
mnriem wants to merge 1 commit 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 1 commit 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 8 tests:

  • Positive: transient=False on win32
  • Negative: transient=True on linux and darwin
  • Source regression guards verifying the platform check exists 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 on lines +1 to +16
"""Tests for Rich Live transient=False on Windows (GitHub issue #2927).

PowerShell 5.1's legacy console host does not support VT escape sequences
reliably. Rich's ``Live(transient=True)`` attempts cursor restoration on
exit, which hangs indefinitely on that console. The fix disables transient
mode when ``sys.platform == "win32"``.

These tests patch ``sys.platform`` and intercept the ``Live`` constructor
to verify the correct ``transient`` value reaches Rich.
"""

from __future__ import annotations

from unittest.mock import MagicMock, patch

import pytest
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 on lines +50 to +60
class TestSelectWithArrowsLiveTransient:
"""Verify that select_with_arrows passes transient=False on Windows."""

def test_transient_false_on_windows(self):
assert _invoke_select_with_arrows("win32") is False

def test_transient_true_on_linux(self):
assert _invoke_select_with_arrows("linux") is True

def test_transient_true_on_macos(self):
assert _invoke_select_with_arrows("darwin") is True
Comment on lines +73 to +75
init_src = Path(__file__).resolve().parent.parent / "src" / "specify_cli" / "commands" / "init.py"
content = init_src.read_text(encoding="utf-8")
assert '_transient = sys.platform != "win32"' in content
Comment on lines +79 to +81
console_src = Path(__file__).resolve().parent.parent / "src" / "specify_cli" / "_console.py"
content = console_src.read_text(encoding="utf-8")
assert '_transient = sys.platform != "win32"' in content

select_with_arrows({"a": "Option A", "b": "Option B"}, "Pick one", "a")

return captured.get("transient")
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