Skip to content

fix: _refresh_hierarchy tolerates an empty screen stack (#147) - #148

Merged
hellices merged 1 commit into
mainfrom
fix/refresh-hierarchy-empty-stack
Aug 1, 2026
Merged

fix: _refresh_hierarchy tolerates an empty screen stack (#147)#148
hellices merged 1 commit into
mainfrom
fix/refresh-hierarchy-empty-stack

Conversation

@hellices

@hellices hellices commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Fixes #147

Problem

Intermittent CI failures in tests/ui/test_ctx_switch.py (seen on PRs #140 and #146, ~20 min rerun each): textual.app.ScreenStackError: No screens on stack. The attempt-1 CI traceback pins the frame:

src/korvid/ui/app.py:1227 in on_resources_updated -> _refresh_hierarchy
src/korvid/ui/app.py:2390 -> screen = self.screen
textual/app.py:1641 -> ScreenStackError

A ResourcesUpdated message dispatched during app teardown lands after the screen stack is emptied; the unguarded App.screen read raises, run_test() re-raises it, and whichever test happened to be running fails.

Fix

Treat "no screen" as "no tree to refresh": catch ScreenStackError around the App.screen read in _refresh_hierarchy and return.

Test

test_refresh_hierarchy_survives_an_empty_screen_stack reproduces the teardown interleaving deterministically (App.screen property raising ScreenStackError) - RED before the fix, GREEN after.

Full gate (make check) green: 2828 passed.

on_resources_updated can be dispatched during app teardown, after the
screen stack is emptied: App.screen then raises ScreenStackError, which
run_test() re-raises and fails whichever test happened to be running -
the intermittent test_ctx_switch CI failures (also seen on PRs #140 and
#146; the CI traceback names this exact frame). No screen simply means
no tree to refresh.

Fixes #147

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 1, 2026 12:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Prevents teardown-time hierarchy refreshes from failing when Textual’s screen stack is empty.

Changes:

  • Catch ScreenStackError during hierarchy refresh.
  • Add a deterministic regression test for issue #147.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/korvid/ui/app.py Safely skips refresh when no screen exists.
tests/ui/test_hierarchy_nav.py Tests empty-screen-stack handling.

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

@my-reviewer-agent my-reviewer-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

이슈 #147의 flaky CI 원인(teardown 중 dispatch된 ResourcesUpdated가 빈 screen stack에서 App.screen을 읽어 ScreenStackError로 전체 테스트 실행을 실패시키는 문제)에 대한 정확하고 최소한의 수정입니다.

  • _refresh_hierarchy에서 self.screen 읽기를 try/except ScreenStackError로 감싸고 조기 반환 — "화면 없음 = 열린 트리 없음" 의미가 자연스럽고, 기존의 isinstance(screen, HierarchyScreen) 가드와도 일관됩니다.
  • 테스트가 property mock으로 teardown 인터리빙을 결정적으로 재현하며 RED→GREEN 검증됨.

Suggestion (비차단): on_resources_updated 경로의 다른 self.screen 접근 지점도 동일한 teardown 레이스에 노출될 수 있으니, 추후 같은 증상이 재발하면 핸들러 진입부에서 공통 가드를 고려해 보세요. 또한 테스트 말미의 assert True는 없어도 무방합니다.

APPROVE

@hellices
hellices merged commit 485c6fc into main Aug 1, 2026
10 checks passed
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.

Flaky CI: test_ctx_switch fails with ScreenStackError ("No screens on stack") on slow runners

2 participants