Skip to content

Commit af70dcd

Browse files
nficanocursoragent
andcommitted
fix: resolve ruff/pyright CI failures in tests and runtime
CI failed fast at the ruff lint step, masking downstream format and pyright failures. Address all of them so the test job is green: - ruff lint: sort imports (I001), rename the LeaseConstraints alias off an all-caps acronym (N817), prefer itertools.pairwise over zip (RUF007), split a compound assertion (PT018), and collapse a subset loop into all()/any() (SIM110). - ruff format: reformat the touched test/runtime modules. - pyright: cast the narrowed session.error details dict to dict[str, Any] so request_id no longer resolves to an unknown type. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent b55eeea commit af70dcd

10 files changed

Lines changed: 31 additions & 27 deletions

File tree

examples/cancel/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import os
88
import sys
99

10-
from arcp import ARCPError, ClientInfo, WebSocketTransport
1110
from arcp import ARCPCancelledError as ARCPCancelled
11+
from arcp import ARCPError, ClientInfo, WebSocketTransport
1212
from arcp.client import ARCPClient
1313

1414
PORT = int(os.environ.get("ARCP_DEMO_PORT", "7883"))

src/arcp/_client/dispatch.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import asyncio
88
from collections.abc import Awaitable, Callable
9-
from typing import TYPE_CHECKING, Any
9+
from typing import TYPE_CHECKING, Any, cast
1010

1111
from .._envelope import Envelope
1212
from .._errors import InternalError, error_from_payload
@@ -77,7 +77,9 @@ async def _on_session_ping(client: ARCPClient, env: Envelope) -> None:
7777
async def _on_session_error(client: ARCPClient, env: Envelope) -> None:
7878
err = error_from_payload(env.payload)
7979
details = env.payload.get("details")
80-
request_id = details.get("request_id") if isinstance(details, dict) else None
80+
request_id = (
81+
cast("dict[str, Any]", details).get("request_id") if isinstance(details, dict) else None
82+
)
8183
# A per-request dispatch failure (e.g. an unknown agent on one submit)
8284
# carries the originating request_id; fail only that request so unrelated
8385
# in-flight job handles keep running (#71). Errors without a request_id

src/arcp/_runtime/_handlers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
SessionPingPayload,
3535
SessionPongPayload,
3636
)
37-
from .._transport.base import TransportClosed
3837
from .._time import now_iso_z as _now_iso
38+
from .._transport.base import TransportClosed
3939
from .._ulid import new_envelope_id, new_job_id
4040
from .credentials import Credential, JobCredentialContext
4141
from .job import Job

src/arcp/_runtime/lease.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,7 @@ def validate_lease_op(
236236
patterns = lease.get(ctx.capability)
237237
# Filesystem targets are canonicalized (resolving `..`) so traversal cannot
238238
# escape a segment-anchored grant before matching.
239-
target = (
240-
canonicalize_target(ctx.target)
241-
if ctx.capability in _PATH_CAPABILITIES
242-
else ctx.target
243-
)
239+
target = canonicalize_target(ctx.target) if ctx.capability in _PATH_CAPABILITIES else ctx.target
244240
if not patterns or not _glob_match(patterns, target):
245241
raise PermissionDeniedError(
246242
f"operation {ctx.capability}:{ctx.target} not permitted by lease"
@@ -271,10 +267,7 @@ def _is_subset_pattern(child_patterns: list[str], parent_patterns: list[str]) ->
271267
containment, not by matching the child *pattern string* against the parent
272268
glob (which let a wider child like `/data/**` pass under `/data/*`).
273269
"""
274-
for cp in child_patterns:
275-
if not any(_glob_lang_subset(cp, pp) for pp in parent_patterns):
276-
return False
277-
return True
270+
return all(any(_glob_lang_subset(cp, pp) for pp in parent_patterns) for cp in child_patterns)
278271

279272

280273
def _patterns_are_subset(child: Lease, parent: Lease) -> bool:

tests/state/test_idempotency_atomic.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
RuntimeInfo,
1212
pair_memory_transports,
1313
)
14+
from arcp._messages.execution import Lease
1415
from arcp._runtime.credentials import (
1516
Credential,
1617
CredentialConstraints,
1718
InMemoryRevocationLog,
1819
JobCredentialContext,
1920
)
20-
from arcp._messages.execution import Lease
2121
from arcp.client import ARCPClient
2222
from arcp.runtime import ARCPRuntime, StaticBearerVerifier
2323

@@ -81,8 +81,12 @@ async def agent(input_value, ctx):
8181
try:
8282
key = "dup-key"
8383
h1, h2 = await asyncio.gather(
84-
c1.submit(agent="a", input=1, idempotency_key=key, lease_request={"model.use": ["m/*"]}),
85-
c2.submit(agent="a", input=1, idempotency_key=key, lease_request={"model.use": ["m/*"]}),
84+
c1.submit(
85+
agent="a", input=1, idempotency_key=key, lease_request={"model.use": ["m/*"]}
86+
),
87+
c2.submit(
88+
agent="a", input=1, idempotency_key=key, lease_request={"model.use": ["m/*"]}
89+
),
8690
)
8791
# Exactly one job and one credential issuance for the reused key.
8892
assert h1.job_id == h2.job_id

tests/state/test_lease_expiry_grace.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
RuntimeInfo,
1818
pair_memory_transports,
1919
)
20-
from arcp._messages.execution import LeaseConstraints as LC
20+
from arcp._messages.execution import LeaseConstraints as LeaseConstraintsMsg
2121
from arcp._runtime.lease import LeaseOpContext, validate_lease_op
2222
from arcp.client import ARCPClient
2323
from arcp.runtime import ARCPRuntime, StaticBearerVerifier
@@ -27,7 +27,7 @@ def test_expiry_grace_window_is_applied_and_configurable() -> None:
2727
now = dt.datetime.now(dt.UTC)
2828
# expires_at 0.5s in the past relative to `now`.
2929
expires = (now - dt.timedelta(seconds=0.5)).isoformat().replace("+00:00", "Z")
30-
constraints = LC(expires_at=expires)
30+
constraints = LeaseConstraintsMsg(expires_at=expires)
3131
lease = {"fs.read": ["*"]}
3232
ctx = LeaseOpContext(capability="fs.read", target="f", now=now)
3333

tests/state/test_list_jobs_filters.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,9 @@ async def slow_agent(input_value, ctx):
285285
id=new_envelope_id(),
286286
type="session.list_jobs",
287287
session_id=welcome.session_id,
288-
payload=SessionListJobsPayload(
289-
filter=ListJobsFilter(created_after=naive_past)
290-
).model_dump(mode="json", exclude_none=True),
288+
payload=SessionListJobsPayload(filter=ListJobsFilter(created_after=naive_past)).model_dump(
289+
mode="json", exclude_none=True
290+
),
291291
)
292292
# Must not raise (previously: TypeError → INTERNAL_ERROR).
293293
await handle_list_jobs(rt, ctx, env)

tests/state/test_resume_rebind_jobs.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ async def agent(input_value, ctx):
6262
async for e in rt.event_log.read_since_seq(welcome.session_id, 1)
6363
if e.get("job_id") == job_id
6464
]
65-
assert any(
66-
e["payload"].get("body", {}).get("message") == "e1" for e in logged
67-
), f"window event e1 not persisted: {logged}"
65+
assert any(e["payload"].get("body", {}).get("message") == "e1" for e in logged), (
66+
f"window event e1 not persisted: {logged}"
67+
)
6868

6969
# --- connection 2: resume ----------------------------------------------
7070
server_b, client_b = pair_memory_transports()
@@ -104,7 +104,8 @@ async def spy(env: Envelope) -> None:
104104

105105
# The seqs B observes are strictly increasing (no collision/gap).
106106
seqs = [s for _, s, _ in seen if s is not None]
107-
assert seqs == sorted(seqs) and len(seqs) == len(set(seqs)), seqs
107+
assert seqs == sorted(seqs), seqs
108+
assert len(seqs) == len(set(seqs)), seqs
108109
finally:
109110
for c in (a, b):
110111
with contextlib.suppress(Exception):

tests/state/test_subscriber_seq_coherent.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import asyncio
66
import contextlib
7+
from itertools import pairwise
78

89
from arcp import (
910
Capabilities,
@@ -33,7 +34,7 @@ def _assert_monotonic_gapfree(seqs: list[int]) -> None:
3334
assert seqs == sorted(seqs), f"not monotonic: {seqs}"
3435
assert len(seqs) == len(set(seqs)), f"duplicate seq: {seqs}"
3536
# gap-free: consecutive values differ by exactly 1.
36-
for a, b in zip(seqs, seqs[1:], strict=False):
37+
for a, b in pairwise(seqs):
3738
assert b == a + 1, f"gap in seq stream: {seqs}"
3839

3940

tests/unit/test_lease_glob.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ def test_single_star_child_is_subset_of_globstar_parent() -> None:
6767

6868

6969
def test_model_use_child_outside_parent_set_rejected() -> None:
70-
assert is_lease_subset({"model.use": ["tier-fast/*-preview/*"]}, {"model.use": ["tier-fast/*"]}) is False
70+
assert (
71+
is_lease_subset({"model.use": ["tier-fast/*-preview/*"]}, {"model.use": ["tier-fast/*"]})
72+
is False
73+
)
7174
assert is_lease_subset({"model.use": ["anthropic/*"]}, {"model.use": ["tier-fast/*"]}) is False
7275

7376

0 commit comments

Comments
 (0)