mirror of
https://github.com/NCBM/plyngent.git
synced 2026-07-23 05:55:16 +08:00
ci/lint: per-file ignores for tests in ruff and basedpyright
Relax ANN/ARG/PLR/C901 and related rules under tests/**; silence noisy basedpyright reports for test fakes and private helpers.
This commit is contained in:
@@ -42,6 +42,23 @@ reportExplicitAny = "hint"
|
|||||||
reportImplicitStringConcatenation = "hint"
|
reportImplicitStringConcatenation = "hint"
|
||||||
reportImportCycles = "hint"
|
reportImportCycles = "hint"
|
||||||
|
|
||||||
|
[[tool.basedpyright.executionEnvironments]]
|
||||||
|
root = "tests"
|
||||||
|
extraPaths = ["src", "."]
|
||||||
|
reportPrivateUsage = "none"
|
||||||
|
reportUnreachable = "none"
|
||||||
|
reportUnusedCallResult = "none"
|
||||||
|
reportUnannotatedClassAttribute = "none"
|
||||||
|
reportUnknownArgumentType = "none"
|
||||||
|
reportUnknownLambdaType = "none"
|
||||||
|
reportUnknownMemberType = "none"
|
||||||
|
reportUnknownVariableType = "none"
|
||||||
|
reportUnknownParameterType = "none"
|
||||||
|
reportMissingParameterType = "none"
|
||||||
|
reportUnusedParameter = "none"
|
||||||
|
reportMissingImports = "none"
|
||||||
|
reportMissingTypeStubs = "none"
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
asyncio_mode = "auto"
|
asyncio_mode = "auto"
|
||||||
asyncio_default_fixture_loop_scope = "function"
|
asyncio_default_fixture_loop_scope = "function"
|
||||||
@@ -129,3 +146,19 @@ allowed-confusables = [
|
|||||||
")",
|
")",
|
||||||
"、"
|
"、"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[tool.ruff.lint.per-file-ignores]
|
||||||
|
"tests/**" = [
|
||||||
|
"ANN", # type annotations often noisy in tests
|
||||||
|
"ARG", # unused fixtures/args are common
|
||||||
|
"ASYNC240", # pathlib in async tests is fine
|
||||||
|
"PLR2004", # magic values in asserts
|
||||||
|
"PLR0911", # many returns in fixtures/helpers
|
||||||
|
"PLR0912", # branching in scripted clients
|
||||||
|
"PLR0915", # long test functions
|
||||||
|
"C901", # complexity in scripted fakes
|
||||||
|
"S101", # assert is the point of tests
|
||||||
|
"TC", # TYPE_CHECKING import churn
|
||||||
|
"TRY003", # long exception messages in tests
|
||||||
|
"FBT", # boolean positional args in helpers
|
||||||
|
]
|
||||||
|
|||||||
@@ -17,6 +17,6 @@ def test_truncate_tool_result_long() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_estimate_message_chars() -> None:
|
def test_estimate_message_chars() -> None:
|
||||||
assert estimate_message_chars(UserChatMessage(content="hello")) == 5 # noqa: PLR2004
|
assert estimate_message_chars(UserChatMessage(content="hello")) == 5
|
||||||
tool = ToolChatMessage(content="abc", tool_call_id="id1")
|
tool = ToolChatMessage(content="abc", tool_call_id="id1")
|
||||||
assert estimate_message_chars(tool) == 6 # noqa: PLR2004
|
assert estimate_message_chars(tool) == 6
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ async def test_run_chat_loop_text_only() -> None:
|
|||||||
assert isinstance(events[0], TextDeltaEvent)
|
assert isinstance(events[0], TextDeltaEvent)
|
||||||
assert events[0].content == "hello"
|
assert events[0].content == "hello"
|
||||||
assert isinstance(events[1], AssistantMessageEvent)
|
assert isinstance(events[1], AssistantMessageEvent)
|
||||||
assert len(messages) == 2 # noqa: PLR2004
|
assert len(messages) == 2
|
||||||
assert len(client.calls) == 1
|
assert len(client.calls) == 1
|
||||||
|
|
||||||
|
|
||||||
@@ -256,7 +256,7 @@ async def test_run_chat_loop_with_tools() -> None:
|
|||||||
assert ToolCallEvent in types
|
assert ToolCallEvent in types
|
||||||
assert ToolResultEvent in types
|
assert ToolResultEvent in types
|
||||||
assert any(isinstance(e, TextDeltaEvent) and e.content == "3" for e in events)
|
assert any(isinstance(e, TextDeltaEvent) and e.content == "3" for e in events)
|
||||||
assert len(client.calls) == 2 # noqa: PLR2004
|
assert len(client.calls) == 2
|
||||||
# second call includes tool result message
|
# second call includes tool result message
|
||||||
assert any(getattr(m, "tool_call_id", None) == "c1" for m in client.calls[1].messages)
|
assert any(getattr(m, "tool_call_id", None) == "c1" for m in client.calls[1].messages)
|
||||||
|
|
||||||
@@ -281,8 +281,8 @@ async def test_max_rounds() -> None:
|
|||||||
client = ScriptedClient([forever, forever, forever])
|
client = ScriptedClient([forever, forever, forever])
|
||||||
messages: list[AnyChatMessage] = [UserChatMessage(content="x")]
|
messages: list[AnyChatMessage] = [UserChatMessage(content="x")]
|
||||||
events = [e async for e in run_chat_loop(client, messages, model="m", tools=registry, max_rounds=2)]
|
events = [e async for e in run_chat_loop(client, messages, model="m", tools=registry, max_rounds=2)]
|
||||||
assert any(isinstance(e, MaxRoundsEvent) and e.rounds == 2 and not e.continued for e in events) # noqa: PLR2004
|
assert any(isinstance(e, MaxRoundsEvent) and e.rounds == 2 and not e.continued for e in events)
|
||||||
assert len(client.calls) == 2 # noqa: PLR2004
|
assert len(client.calls) == 2
|
||||||
|
|
||||||
|
|
||||||
async def test_max_rounds_continue_hook() -> None:
|
async def test_max_rounds_continue_hook() -> None:
|
||||||
@@ -325,7 +325,7 @@ async def test_max_rounds_continue_hook() -> None:
|
|||||||
assert len(asks) == 1
|
assert len(asks) == 1
|
||||||
assert any(isinstance(e, MaxRoundsEvent) and e.continued for e in events)
|
assert any(isinstance(e, MaxRoundsEvent) and e.continued for e in events)
|
||||||
assert any(isinstance(e, TextDeltaEvent) and e.content == "done" for e in events)
|
assert any(isinstance(e, TextDeltaEvent) and e.content == "done" for e in events)
|
||||||
assert len(client.calls) == 3 # noqa: PLR2004
|
assert len(client.calls) == 3
|
||||||
|
|
||||||
|
|
||||||
async def test_max_rounds_async_continue_hook() -> None:
|
async def test_max_rounds_async_continue_hook() -> None:
|
||||||
@@ -373,7 +373,7 @@ async def test_max_rounds_async_continue_hook() -> None:
|
|||||||
async def test_default_max_rounds_is_generous() -> None:
|
async def test_default_max_rounds_is_generous() -> None:
|
||||||
from plyngent.agent.loop import DEFAULT_MAX_ROUNDS
|
from plyngent.agent.loop import DEFAULT_MAX_ROUNDS
|
||||||
|
|
||||||
assert DEFAULT_MAX_ROUNDS >= 16 # noqa: PLR2004
|
assert DEFAULT_MAX_ROUNDS >= 16
|
||||||
|
|
||||||
|
|
||||||
async def test_chat_agent_memory_roundtrip() -> None:
|
async def test_chat_agent_memory_roundtrip() -> None:
|
||||||
@@ -385,13 +385,13 @@ async def test_chat_agent_memory_roundtrip() -> None:
|
|||||||
assert any(isinstance(e, TextDeltaEvent) and e.content == "yo" for e in events)
|
assert any(isinstance(e, TextDeltaEvent) and e.content == "yo" for e in events)
|
||||||
|
|
||||||
loaded = await store.list_messages(session.sid)
|
loaded = await store.list_messages(session.sid)
|
||||||
assert len(loaded) == 2 # noqa: PLR2004
|
assert len(loaded) == 2
|
||||||
assert isinstance(loaded[0], UserChatMessage)
|
assert isinstance(loaded[0], UserChatMessage)
|
||||||
assert loaded[0].content == "hi"
|
assert loaded[0].content == "hi"
|
||||||
|
|
||||||
agent2 = ChatAgent(client, model="m", memory=store, session_id=session.sid)
|
agent2 = ChatAgent(client, model="m", memory=store, session_id=session.sid)
|
||||||
await agent2.load_history()
|
await agent2.load_history()
|
||||||
assert len(agent2.messages) == 2 # noqa: PLR2004
|
assert len(agent2.messages) == 2
|
||||||
await store.close()
|
await store.close()
|
||||||
|
|
||||||
|
|
||||||
@@ -477,7 +477,7 @@ async def test_chat_agent_retry_after_failure() -> None:
|
|||||||
assert any(isinstance(e, TextDeltaEvent) and e.content == "recovered" for e in events)
|
assert any(isinstance(e, TextDeltaEvent) and e.content == "recovered" for e in events)
|
||||||
assert agent.pending_retry_text is None
|
assert agent.pending_retry_text is None
|
||||||
loaded = await store.list_messages(session.sid)
|
loaded = await store.list_messages(session.sid)
|
||||||
assert len(loaded) == 2 # noqa: PLR2004
|
assert len(loaded) == 2
|
||||||
assert isinstance(loaded[0], UserChatMessage)
|
assert isinstance(loaded[0], UserChatMessage)
|
||||||
assert loaded[0].content == "ping"
|
assert loaded[0].content == "ping"
|
||||||
await store.close()
|
await store.close()
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ def test_open_in_editor_splits_args(tmp_path: Path, monkeypatch: pytest.MonkeyPa
|
|||||||
path = tmp_path / "plyngent.toml"
|
path = tmp_path / "plyngent.toml"
|
||||||
calls: list[list[str]] = []
|
calls: list[list[str]] = []
|
||||||
|
|
||||||
def fake_run(argv: list[str], check: bool = False) -> object: # noqa: FBT001, FBT002
|
def fake_run(argv: list[str], check: bool = False) -> object:
|
||||||
del check
|
del check
|
||||||
calls.append(list(argv))
|
calls.append(list(argv))
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ def test_config_edit_command(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) ->
|
|||||||
monkeypatch.setenv("EDITOR", "true")
|
monkeypatch.setenv("EDITOR", "true")
|
||||||
calls: list[list[str]] = []
|
calls: list[list[str]] = []
|
||||||
|
|
||||||
def fake_run(argv: list[str], check: bool = False) -> object: # noqa: FBT001, FBT002
|
def fake_run(argv: list[str], check: bool = False) -> object:
|
||||||
del check
|
del check
|
||||||
calls.append(list(argv))
|
calls.append(list(argv))
|
||||||
|
|
||||||
|
|||||||
@@ -138,8 +138,8 @@ async def test_history(state: ReplState, capsys: pytest.CaptureFixture[str]) ->
|
|||||||
|
|
||||||
async def test_rounds(state: ReplState) -> None:
|
async def test_rounds(state: ReplState) -> None:
|
||||||
assert await handle_slash(state, "/rounds 40") is True
|
assert await handle_slash(state, "/rounds 40") is True
|
||||||
assert state.max_rounds == 40 # noqa: PLR2004
|
assert state.max_rounds == 40
|
||||||
assert state.agent.max_rounds == 40 # noqa: PLR2004
|
assert state.agent.max_rounds == 40
|
||||||
|
|
||||||
|
|
||||||
async def test_status_shows_context_chars(
|
async def test_status_shows_context_chars(
|
||||||
|
|||||||
@@ -112,9 +112,9 @@ async def test_auto_retry_eventually_succeeds(monkeypatch: pytest.MonkeyPatch) -
|
|||||||
delays=(0.01, 0.01, 0.01),
|
delays=(0.01, 0.01, 0.01),
|
||||||
)
|
)
|
||||||
assert ok is True
|
assert ok is True
|
||||||
assert client.calls == 3 # noqa: PLR2004
|
assert client.calls == 3
|
||||||
loaded = await store.list_messages(session.sid)
|
loaded = await store.list_messages(session.sid)
|
||||||
assert len(loaded) == 2 # noqa: PLR2004
|
assert len(loaded) == 2
|
||||||
assert isinstance(loaded[0], UserChatMessage)
|
assert isinstance(loaded[0], UserChatMessage)
|
||||||
assert loaded[0].content == "hello"
|
assert loaded[0].content == "hello"
|
||||||
await store.close()
|
await store.close()
|
||||||
@@ -205,7 +205,7 @@ async def test_manual_retry_after_exhausted(monkeypatch: pytest.MonkeyPatch) ->
|
|||||||
assert ok2 is True
|
assert ok2 is True
|
||||||
assert agent.pending_retry_text is None
|
assert agent.pending_retry_text is None
|
||||||
loaded = await store.list_messages(session.sid)
|
loaded = await store.list_messages(session.sid)
|
||||||
assert len(loaded) == 2 # noqa: PLR2004
|
assert len(loaded) == 2
|
||||||
assert isinstance(loaded[0], UserChatMessage)
|
assert isinstance(loaded[0], UserChatMessage)
|
||||||
assert loaded[0].content == "hold-me"
|
assert loaded[0].content == "hold-me"
|
||||||
await store.close()
|
await store.close()
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ def test_agent_section_defaults(tmp_path: Path) -> None:
|
|||||||
_ = path.write_text("", encoding="utf-8")
|
_ = path.write_text("", encoding="utf-8")
|
||||||
store = load(path)
|
store = load(path)
|
||||||
assert store.agent_config.system_prompt == ""
|
assert store.agent_config.system_prompt == ""
|
||||||
assert store.agent_config.max_tool_result_chars == 32_000 # noqa: PLR2004
|
assert store.agent_config.max_tool_result_chars == 32_000
|
||||||
assert store.agent_config.parallel_tools is True
|
assert store.agent_config.parallel_tools is True
|
||||||
assert store.agent_config.confirm_destructive is True
|
assert store.agent_config.confirm_destructive is True
|
||||||
assert store.agent_config.path_denylist == []
|
assert store.agent_config.path_denylist == []
|
||||||
assert store.agent_config.max_context_chars == 200_000 # noqa: PLR2004
|
assert store.agent_config.max_context_chars == 200_000
|
||||||
|
|
||||||
|
|
||||||
def test_agent_section_parse(tmp_path: Path) -> None:
|
def test_agent_section_parse(tmp_path: Path) -> None:
|
||||||
@@ -36,8 +36,8 @@ max_context_chars = 5000
|
|||||||
)
|
)
|
||||||
store = load(path)
|
store = load(path)
|
||||||
assert store.agent_config.system_prompt == "Be brief."
|
assert store.agent_config.system_prompt == "Be brief."
|
||||||
assert store.agent_config.max_tool_result_chars == 100 # noqa: PLR2004
|
assert store.agent_config.max_tool_result_chars == 100
|
||||||
assert store.agent_config.parallel_tools is False
|
assert store.agent_config.parallel_tools is False
|
||||||
assert store.agent_config.confirm_destructive is False
|
assert store.agent_config.confirm_destructive is False
|
||||||
assert store.agent_config.path_denylist == ["/secrets/", ".ssh/"]
|
assert store.agent_config.path_denylist == ["/secrets/", ".ssh/"]
|
||||||
assert store.agent_config.max_context_chars == 5000 # noqa: PLR2004
|
assert store.agent_config.max_context_chars == 5000
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ async def test_append_and_list_messages(store: MemoryStore) -> None:
|
|||||||
assert row1.seq == 1
|
assert row1.seq == 1
|
||||||
|
|
||||||
messages = await store.list_messages(session.sid)
|
messages = await store.list_messages(session.sid)
|
||||||
assert len(messages) == 2 # noqa: PLR2004
|
assert len(messages) == 2
|
||||||
assert isinstance(messages[0], UserChatMessage)
|
assert isinstance(messages[0], UserChatMessage)
|
||||||
assert messages[0].content == "hello"
|
assert messages[0].content == "hello"
|
||||||
assert isinstance(messages[1], AssistantChatMessage)
|
assert isinstance(messages[1], AssistantChatMessage)
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ def test_pty_session_limit_continue(workspace: object) -> None:
|
|||||||
second = call_sync(open_pty, ["sleep", "30"])
|
second = call_sync(open_pty, ["sleep", "30"])
|
||||||
assert "session_id=" in first
|
assert "session_id=" in first
|
||||||
assert "session_id=" in second
|
assert "session_id=" in second
|
||||||
assert PtyManager.max_sessions >= 2 # noqa: PLR2004
|
assert PtyManager.max_sessions >= 2
|
||||||
finally:
|
finally:
|
||||||
PtyManager.close_all()
|
PtyManager.close_all()
|
||||||
PtyManager.configure(max_sessions=previous)
|
PtyManager.configure(max_sessions=previous)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ def test_tree_max_entries(workspace: object) -> None:
|
|||||||
assert "more entries not shown" in out
|
assert "more entries not shown" in out
|
||||||
# only first 10 of 60 files listed as entries
|
# only first 10 of 60 files listed as entries
|
||||||
listed = [line for line in out.splitlines() if line.strip().endswith(".txt")]
|
listed = [line for line in out.splitlines() if line.strip().endswith(".txt")]
|
||||||
assert len(listed) == 10 # noqa: PLR2004
|
assert len(listed) == 10
|
||||||
|
|
||||||
|
|
||||||
def test_tree_origin_subdir(workspace: object) -> None:
|
def test_tree_origin_subdir(workspace: object) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user