CLI: a closed stdout pipe exits 141 silently (was E_INTERNAL); example avoids head under pipefail
ci / test (3.12) (push) Failing after 8s
ci / test (3.13) (push) Failing after 10s

Found by the P10 fresh-VM run: `simurg inspect … | head` raised BrokenPipeError, reported as
an internal error, and stopped examples/gsa_demo.sh (set -o pipefail). run_guarded now flushes
stdout inside the guard and maps BrokenPipeError to ExitCode.SIGPIPE (141) without a message.
p10.sh: SKIP_DOCKER/SKIP_CONDA, clearer digest report; p10t.sh runs build+pip+tutorial only.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01814GKVzZVL3FuF3DeiZXhv
This commit is contained in:
kemalandClaude Opus 5.5 committed 2026-09-28 23:14:47 +01:00
1 parent 92416397fe
commit bc93e00318
6 files changed
+38 -6

No files matched your search

+15
View File
@@ -93,3 +93,18 @@ def test_locale_independent_output(tmp_path) -> None: # type: ignore[no-untyped
assert r.returncode == 0, r.stderr
outs.add(r.stdout)
assert len(outs) == 1
def test_closed_stdout_is_not_an_internal_error(tmp_path) -> None: # type: ignore[no-untyped-def]
# `simurg inspect … | head`: the reader goes away; the CLI must exit like a SIGPIPE'd tool (141), silently
f = _files(tmp_path)
p = subprocess.Popen(
[sys.executable, "-m", "simurg.cli.main", "inspect", "--json", str(f["bpm"]), str(f["egt"]), str(f["idat"])],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
assert p.stdout is not None and p.stderr is not None
p.stdout.close() # nobody reads stdout
err = p.stderr.read().decode()
assert p.wait() == 141, err
assert "E_INTERNAL" not in err and "Traceback" not in err and "Exception ignored" not in err