@kernlang/review-python 3.4.6-canary.42.1.df0d73a1 → 3.4.6-canary.44.1.a85ee2e8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mapper.js CHANGED
@@ -594,7 +594,10 @@ function extractFastApiSuccessStatusCodes(decText, fnDef, source) {
594
594
  // rather than a name whitelist; the API_SUCCESS_STATUS_CODES filter
595
595
  // keeps the noise tax low.
596
596
  const mutationCodes = new Set();
597
- const mutateRe = /\b[A-Za-z_]\w*\.status_code\s*=\s*([^\n;]+)/g;
597
+ // `=(?!=)` distinguishes assignment from `==` comparison so
598
+ // `if response.status_code == 200:` doesn't masquerade as a dynamic
599
+ // mutation (forge round, Claude engine).
600
+ const mutateRe = /\b[A-Za-z_]\w*\.status_code\s*=(?!=)\s*([^\n;]+)/g;
598
601
  for (const match of bodyText.matchAll(mutateRe)) {
599
602
  const code = parseFastApiStatusValue(match[1].trim());
600
603
  if (code === undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kernlang/review-python",
3
- "version": "3.4.6-canary.42.1.df0d73a1",
3
+ "version": "3.4.6-canary.44.1.a85ee2e8",
4
4
  "description": "Python concept mapper for kern review — tree-sitter based",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -8,8 +8,8 @@
8
8
  "dependencies": {
9
9
  "tree-sitter": "^0.25.0",
10
10
  "tree-sitter-python": "^0.25.0",
11
- "@kernlang/core": "3.4.6-canary.42.1.df0d73a1",
12
- "@kernlang/review": "3.4.6-canary.42.1.df0d73a1"
11
+ "@kernlang/core": "3.4.6-canary.44.1.a85ee2e8",
12
+ "@kernlang/review": "3.4.6-canary.44.1.a85ee2e8"
13
13
  },
14
14
  "devDependencies": {
15
15
  "ts-morph": "^28.0.0",
package/src/mapper.ts CHANGED
@@ -686,7 +686,10 @@ function extractFastApiSuccessStatusCodes(
686
686
  // rather than a name whitelist; the API_SUCCESS_STATUS_CODES filter
687
687
  // keeps the noise tax low.
688
688
  const mutationCodes = new Set<number>();
689
- const mutateRe = /\b[A-Za-z_]\w*\.status_code\s*=\s*([^\n;]+)/g;
689
+ // `=(?!=)` distinguishes assignment from `==` comparison so
690
+ // `if response.status_code == 200:` doesn't masquerade as a dynamic
691
+ // mutation (forge round, Claude engine).
692
+ const mutateRe = /\b[A-Za-z_]\w*\.status_code\s*=(?!=)\s*([^\n;]+)/g;
690
693
  for (const match of bodyText.matchAll(mutateRe)) {
691
694
  const code = parseFastApiStatusValue(match[1].trim());
692
695
  if (code === undefined) sawDynamic = true;
@@ -339,6 +339,25 @@ def create():
339
339
  expect(routes[0].payload.successStatusCodes).toEqual([202]);
340
340
  });
341
341
 
342
+ it('does NOT treat `== 200` comparison as a dynamic mutation (forge round, Claude engine)', () => {
343
+ // `if response.status_code == 200:` is a comparison, not an assignment.
344
+ // Without the `=(?!=)` lookahead, the mutation regex captured `200) ...`
345
+ // as a dynamic RHS and incorrectly marked the route resolved=false.
346
+ const routes = routePayloads(`
347
+ from fastapi import Response
348
+
349
+ @router.post("/items", status_code=201)
350
+ def create(response: Response):
351
+ if response.status_code == 200:
352
+ return {"unreachable": True}
353
+ return {"id": 1}
354
+ `);
355
+ expect(routes[0].payload.successStatusCodesResolved).toBe(true);
356
+ // Decorator says 201, plain returns inherit it. The `==` comparison
357
+ // contributes nothing.
358
+ expect(routes[0].payload.successStatusCodes).toEqual([201]);
359
+ });
360
+
342
361
  it('detects status_code mutation under non-conventional Response param name (Codex impl-review #2)', () => {
343
362
  // Param injected as `out: Response` instead of the conventional
344
363
  // `response`. Without broadened receiver matching, mutation is missed and