Repository navigation
client-method-shape: check a walk's first request, and pass a stream - #10
Merged
Merged
Conversation
A walk's one positional argument is now read: a path string, or PageRequest(<path string>, body=<request parameter>, write=<WRITER>) and nothing else. Beside a PageRequest, params= and idempotency_key= are refused, which is when headgate 0.8.0 raises; a walk of GETs keeps idempotency_key=. Form (g): an async def whose one statement is `async with self.stream(...) as <s>:` holding only `async for <c> in <s>.aiter_bytes():` holding only `yield <c>`, no else. The stream's arguments take the forward checks, and only the keywords a GET stream takes. The item may be in one pair of parentheses. Fixtures for every new clause; each clause was deleted in turn and each deletion fails a fixture. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ures Raise the headgate floor to 0.8.0, whose PageRequest (body=, write=) and paginate the rule now checks; the lock moves headgate 0.7.0 to 0.8.0 and nothing else. A PageRequest may carry the query as params=params, the only way to give a walk of POSTs one; any other params= value is reported. The header says a PageRequest without write= (a JSON body) is reported, and discloses that an Idempotency-Key in headers= beside a PageRequest is not read, and that line and server-sent-event streams still need an allow comment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Review addressed in c670e85:
Gates against headgate 0.8.0, all passing: 🤖 Generated with Claude Code |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes
Two forms
client-method-shapemishandled. Both were measured by running this repo's engine and the source rule's engine on the same cases.1. A walk's first request.
self.paginate(...)'s one positional argument was never read. A computed path (self.paginate(_path_for(year), ...)), a second positional argument, or aPageRequestbuilt any other way all passed. The walk's first request must now be:PageRequest(<path string>, body=<request parameter>, write=<WRITER>)with nothing else in it (headgate 0.8.0's walk of POSTs). The writer is an UPPER_CASE name, public or_-prefixed, the same asbody='s writer.Next to a
PageRequest,params=andidempotency_key=are refused, because headgate raises for both there. A walk of GETs can still passidempotency_key=, sopass/paginate_optionsstill passes. There is no walk leg to update: the envelope leg, and the walk leg that paginated it, were already removed from this rule.2. Form (g), streams. A stream used to be reported at its
defline. The rule now passes an async def whose one statement isasync with self.stream(...) as <s>:holding onlyasync for <c> in <s>.aiter_bytes():holding onlyyield <c>, with noelse:.<s>and<c>must be plain names.self.stream(...)takes the same forward checks as a verb (bad-forward-args-common, including the module-levelexpect=and knob rules).params,headers,timeout,deadline,retryandfollow_redirects. So a body option,expect=,cache_ttl=,method=andlast_event_id=are all reported.as, as(self.stream(...)) as s, or inside two pairs of parentheses is still reported. These cases are listed under KNOWN GAPS.The rule header now covers (e) and (g) and the CHANGED-from-source items, and its note mentions both forms.
verifier.mdis regenerated,conventions.mddocuments the stream and the walk of POSTs, andCHANGELOG.mdhas two entries under Unreleased.Fixtures
limit=and the original fault kept. Also the computed-path andto_builtins(...)/extra=variants, pluswalk_first_request_another_constructor,walk_page_request_second_positional,walk_page_request_lowercase_writer,walk_of_posts_idempotency_key,walk_of_posts_params, and 18stream_*cases (plainwith, plainfor, two items, noas, wrong callee, number timeout,expect=, body, other iterator, chunk size, other object, yields something else, yields twice,else:, work before or after the loop, stream or chunk bound to an attribute).expect=moved to a module name,walk_of_posts_public_writerandstream_parenthesised.Mutation check
Each new clause was deleted (or narrowed, for one arm of an
any) in turn, and the rule's fixtures were rerun: 44 of 44 mutations fail at least one fixture. Three qualifiers started out inert. Two were made live with new fixtures:kind: identifieron the loop target and on theasalias, via the attribute-binding cases. The third,kind: callon the loop's iterable, was dropped because the grammar makes it redundant. The source's "inside an async def" check was not carried over, because Python's parser already turns that case into a parse-error.Checklist
uv run ruff check,uv run ruff format --checkanduv run ty checkpass, with no suppression commentsuv run python -m pytest --covpasses, at or above the coverage floor (96.82%, floor 96; 1872 passed)uv run python scripts/gen_rule_docs.py --checkpasses, and the skill's references describe the new behaviouruv run headgate-verify examples/passes with no findingsCHANGELOG.mdhas an entry under "Unreleased"uv lock --checkpassesThe checks above were run locally.
🤖 Generated with Claude Code