Skip to content

Commit 7fc0c58

Browse files
committed
chore(tasks): lessons from CI test failures (Rich style cache, pipe reap)
1 parent b300e71 commit 7fc0c58

1 file changed

Lines changed: 16 additions & 0 deletions

File tree

tasks/lessons.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,19 @@ Format: trigger → rule.
114114
the FULL Bash command text, so a debug payload containing the trigger
115115
substring (`gh pr create`) re-triggers the gate on your own debug command —
116116
split the substring (`"gh pr %s" create`) when reproducing.
117+
- **When a color-assertion test passes locally but fails on CI** (or vice
118+
versa) with quantized SGR codes (`38;5;N` where `38;2;r;g;b` was expected),
119+
suspect Rich's per-instance ANSI memoization: `Style.render` caches its SGR
120+
string at FIRST render with whatever console color system was active, and
121+
value-equal combined styles (`style + bold`) are shared process-wide via
122+
`lru_cache`. Whichever test renders a style first (under the suite's
123+
TERM/COLORTERM) poisons every later console. Reproduce with
124+
`env -u COLORTERM pytest tests/ui_and_conv <target>`; fix by asserting on
125+
span Style objects (color triplets), never on rendered ANSI.
126+
- **asyncio `Process.wait()` needs EOF on every pipe, not just child exit.**
127+
`wait()` resolves only in `_call_connection_lost`, gated on ALL pipe
128+
transports being disconnected. A bounded `stdout.read(n)` that leaves the
129+
reader flow-control-paused on a full buffer blocks EOF forever — so
130+
`kill(); await proc.wait()` deadlocks even though the child is dead
131+
(Linux pipe dynamics hit this deterministically; macOS rarely). After
132+
killing a child with stdout=PIPE, drain the stream to EOF before waiting.

0 commit comments

Comments
 (0)