Skip to content

fix(entrypoints): http_methods carries HTTP methods only (#213) - #219

Merged
rahlk merged 1 commit into
mainfrom
fix/issue-213-non-http-methods
Sep 15, 2026
Merged

rahlk merged 1 commit into
mainfrom
fix/issue-213-non-http-methods

Conversation

@rahlk

@rahlk rahlk commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Closes #213.

The bug

_methods_of's match_suffix branch returned the matched suffix verbatim, and the shipped heuristic.http-verb rule matches .websocket alongside the real verbs:

- id: heuristic.http-verb
  match: "{*,*.*}.{get,post,put,patch,delete,head,options,websocket}"
  methods: {from: match_suffix}

So @app.websocket("/ws") produced http_methods: ["WEBSOCKET"]. Reproduced before the fix:

websocket: [('heuristic.http-verb', '/ws', ['WEBSOCKET'])]
get      : [('heuristic.http-verb', '/ws', ['GET'])]

http_methods is what a consumer filters on to separate routes from other entrypoints, so a value that is not a method is worse there than an empty list — a query for POST endpoints is unaffected, but one enumerating distinct methods reports a method that does not exist.

The fix

One filter, matching what the class-dispatch path at the bottom of the same module already did: emit [verb.upper()] only when verb.lower() in _HTTP_VERBS, else []. The entrypoint is still recorded — only the method list changes, and rule (heuristic.http-verb) remains how the shape is identified. fastapi.websocket, a separate rule with no methods: spec, already yielded [] and is untouched.

Tests

Three, in test_entrypoint_decorators.py: the websocket reproducer (entrypoint recorded, route intact, http_methods == []), @app.get still yielding ["GET"], and an invariant test that walks every shipped match_suffix rule, probes each literal suffix its pattern accepts, and asserts the union of everything emitted is a subset of _HTTP_VERBS — so a future rule with a non-verb suffix fails here rather than shipping junk.

Gates, run on b120aed

Gate Result
Fixture suite 522 passed, 11 skipped (519 before, +3 new)
Schema conformance 2.0.0 at L1–L4, each validates against Analysis
Monotonicity 78 → 79 → 165 → 262 ids, 0 lost
Determinism two -a 4 runs byte-identical (126592 B)
Cross-projection 262 JSON ids vs 284 graph ids, 0 missing

Caveats

  • Behaviour change for anyone reading WEBSOCKET out of http_methods today. No schema shape change: http_methods stays List[str], schema_version stays 2.0.0.
  • Propagation: none. codeanalyzer-typescript already filters both its match_suffix and export_name paths (matching.ts:92,103, its fix(neo4j): the graph projection carries the facts analysis.json carries #206); codeanalyzer-java has no http_methods surface at all yet; python-sdk carries http_methods only on its TypeScript model, and this changes a value rather than a shape.

`_methods_of`'s `match_suffix` branch returned the matched suffix verbatim, and
the shipped `heuristic.http-verb` rule matches `.websocket` alongside the real
verbs -- so `@app.websocket("/ws")` produced `http_methods: ["WEBSOCKET"]`.
`http_methods` is what a consumer filters on to separate routes from other
entrypoints, so a value that is not a method is worse there than an empty list: a
query for POST endpoints is unaffected, but one enumerating distinct methods
reports a method that does not exist.

The branch now emits a verb only when it is one, matching what the class-dispatch
path at the bottom of the module already did. The entrypoint itself is still
recorded -- only the method list changes, and `rule` remains how the shape is
identified.

codeanalyzer-typescript already filters both its `match_suffix` and `export_name`
paths (its #206, the Astro `ALL` export); this closes the same gap here.
@rahlk
rahlk merged commit b75b7dd into main Sep 15, 2026
@rahlk
rahlk deleted the fix/issue-213-non-http-methods branch September 15, 2026 01:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

match_suffix emits non-HTTP methods (WEBSOCKET) into http_methods

1 participant