fix(test): restore headless unit tests broken by PTY check in e719022
test / integration-docker (push) Successful in 15s
test / unit (push) Successful in 39s
Update Quality Badges / update-badges (push) Successful in 45s
lint / lint (push) Successful in 2m36s
test / integration-firecracker (push) Successful in 5m15s
test / coverage (push) Successful in 16s
test / publish-infra (push) Successful in 1m39s

The PTY check added in e719022 calls sys.stdin.fileno() which raises
io.UnsupportedOperation under pytest's stdin capture. Guard the fileno()
call with a try/except so the check degrades cleanly to "not a tty"
instead of crashing, then stub os.isatty in the test setUp so headless
unit tests aren't blocked on a real TTY.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 23:28:55 +00:00
parent 12b071833d
commit 2e0414f969
2 changed files with 9 additions and 1 deletions
+6 -1
View File
@@ -14,6 +14,7 @@ the private orchestrator `_launch_bottle`.
from __future__ import annotations from __future__ import annotations
import argparse import argparse
import io
import os import os
import shutil import shutil
import sys import sys
@@ -195,7 +196,11 @@ def _start_headless(
path, so the agent still execs on the inherited stdio/PTY — an path, so the agent still execs on the inherited stdio/PTY — an
orchestrator allocates that PTY and relays it to its orchestrator allocates that PTY and relays it to its
desktop/mobile clients.""" desktop/mobile clients."""
if not os.isatty(sys.stdin.fileno()): try:
stdin_fd = sys.stdin.fileno()
except io.UnsupportedOperation:
stdin_fd = -1
if not os.isatty(stdin_fd):
die( die(
"--headless requires a PTY on stdin; run via:\n" "--headless requires a PTY on stdin; run via:\n"
" script -q /dev/null ./cli.py start ..." " script -q /dev/null ./cli.py start ..."
+3
View File
@@ -69,6 +69,9 @@ class TestCmdStartHeadless(unittest.TestCase):
self._modal = patch.object(tui_mod, "name_color_modal").start() self._modal = patch.object(tui_mod, "name_color_modal").start()
patch.dict(os.environ, {}, clear=False).start() patch.dict(os.environ, {}, clear=False).start()
os.environ.pop("BOT_BOTTLE_BACKEND", None) os.environ.pop("BOT_BOTTLE_BACKEND", None)
# PTY check uses os.isatty(sys.stdin.fileno()); stub both so
# headless unit tests aren't blocked on a real TTY.
patch("bot_bottle.cli.start.os.isatty", return_value=True).start()
self.addCleanup(patch.stopall) self.addCleanup(patch.stopall)
def _spec(self): def _spec(self):