Skip to content

Commit 94f89de

Browse files
test: harden MessageDict mypy fixtures and restore search parity
1 parent 32e8019 commit 94f89de

5 files changed

Lines changed: 35 additions & 13 deletions

File tree

tests/mypy_types/message_dict_invalid.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from models.session import MessageDict, UserMessageDict
44

55
user_msg: UserMessageDict = {"role": "user", "text": "hello"}
6-
_ = user_msg["thinking"]
6+
_ = user_msg["thinking"] # expect: typeddict-item thinking
77

88
union_msg: MessageDict = {"role": "user", "text": "hello"}
9-
_ = union_msg["thinking"]
9+
_ = union_msg["thinking"] # expect: typeddict-item thinking
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
"""Positive fixture: discriminant narrowing allows role-specific fields."""
22

3-
from models.session import MessageDict, UserMessageDict
3+
from models.session import AssistantMessageDict, MessageDict, UserMessageDict
44

5-
messages: list[MessageDict] = [{"role": "user", "text": "hello"}]
5+
messages: list[MessageDict] = [
6+
{"role": "user", "text": "hello"},
7+
{"role": "assistant", "text": "hi", "thinking": "hmm"},
8+
]
69
for msg in messages:
710
if msg["role"] == "user":
811
narrowed: UserMessageDict = msg
9-
_ = narrowed.get("slug")
12+
_ = narrowed["slug"]
13+
elif msg["role"] == "assistant":
14+
narrowed_asst: AssistantMessageDict = msg
15+
_ = narrowed_asst["thinking"]

tests/test_message_dict_mypy.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
MYPY_TYPES_DIR = REPO_ROOT / "tests" / "mypy_types"
1414

1515
_INVALID_FIXTURE = "message_dict_invalid.py"
16-
_INVALID_ERROR_LINES = (6, 9)
16+
_EXPECT_MARKER = "expect: typeddict-item"
1717

1818

1919
def _run_mypy_on(path: Path) -> subprocess.CompletedProcess[str]:
@@ -31,6 +31,7 @@ def _run_mypy_on(path: Path) -> subprocess.CompletedProcess[str]:
3131
capture_output=True,
3232
text=True,
3333
check=False,
34+
timeout=60.0,
3435
)
3536

3637

@@ -39,6 +40,19 @@ def _typeddict_item_error_lines(output: str, fixture_name: str) -> set[int]:
3940
return {int(match.group(1)) for match in re.finditer(pattern, output)}
4041

4142

43+
def _invalid_fixture_expectations(fixture_path: Path) -> tuple[set[int], list[str]]:
44+
expected_lines: set[int] = set()
45+
expected_tokens: list[str] = []
46+
for lineno, line in enumerate(fixture_path.read_text(encoding="utf-8").splitlines(), start=1):
47+
if _EXPECT_MARKER not in line:
48+
continue
49+
expected_lines.add(lineno)
50+
suffix = line.split(_EXPECT_MARKER, 1)[1].strip()
51+
if suffix:
52+
expected_tokens.append(suffix)
53+
return expected_lines, expected_tokens
54+
55+
4256
@pytest.mark.parametrize(
4357
("fixture_name", "should_pass"),
4458
[
@@ -47,14 +61,18 @@ def _typeddict_item_error_lines(output: str, fixture_name: str) -> set[int]:
4761
],
4862
)
4963
def test_message_dict_mypy_fixtures(fixture_name: str, should_pass: bool) -> None:
50-
result = _run_mypy_on(MYPY_TYPES_DIR / fixture_name)
64+
fixture_path = MYPY_TYPES_DIR / fixture_name
65+
result = _run_mypy_on(fixture_path)
5166
output = result.stdout + result.stderr
5267
if should_pass:
5368
assert result.returncode == 0, output
5469
else:
5570
assert result.returncode != 0
5671
error_lines = _typeddict_item_error_lines(output, fixture_name)
57-
assert error_lines >= set(_INVALID_ERROR_LINES), (
58-
f"expected typeddict-item on lines {_INVALID_ERROR_LINES}, "
72+
expected_lines, expected_tokens = _invalid_fixture_expectations(fixture_path)
73+
assert error_lines >= expected_lines, (
74+
f"expected typeddict-item on lines {sorted(expected_lines)}, "
5975
f"got {sorted(error_lines)}: {output}"
6076
)
77+
for token in expected_tokens:
78+
assert token in output, f"expected mypy output to mention {token!r}: {output}"

utils/jsonl_parser.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ def _fallback_message(entry: dict[str, Any], role: RoleLiteral) -> MessageDict:
114114
"parent_uuid": base["parent_uuid"],
115115
"timestamp": base["timestamp"],
116116
"is_sidechain": base["is_sidechain"],
117-
"progress_type": "",
118-
"data": {},
119117
}
120118
return progress_msg
121119
result_msg: ResultMessageDict = {

utils/search_index.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,8 @@ def message_searchable_text(msg: MessageDict) -> str:
385385
raw_text = msg.get("text", "")
386386
text = raw_text if isinstance(raw_text, str) else ""
387387
elif role == "system":
388-
raw_content = msg.get("content", "")
389-
content = raw_content if isinstance(raw_content, str) else ""
388+
raw_text = msg.get("text", "") or msg.get("content", "") or ""
389+
text = raw_text if isinstance(raw_text, str) else ""
390390
elif role == "result":
391391
raw_text = msg.get("text", "") or msg.get("content", "") or ""
392392
text = raw_text if isinstance(raw_text, str) else ""

0 commit comments

Comments
 (0)