@kernlang/python 3.5.2

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.
Files changed (63) hide show
  1. package/LICENSE +678 -0
  2. package/README.md +26 -0
  3. package/dist/codegen-body-python.d.ts +152 -0
  4. package/dist/codegen-body-python.js +1648 -0
  5. package/dist/codegen-body-python.js.map +1 -0
  6. package/dist/codegen-helpers.d.ts +21 -0
  7. package/dist/codegen-helpers.js +352 -0
  8. package/dist/codegen-helpers.js.map +1 -0
  9. package/dist/codegen-python.d.ts +17 -0
  10. package/dist/codegen-python.js +106 -0
  11. package/dist/codegen-python.js.map +1 -0
  12. package/dist/fastapi-middleware.d.ts +8 -0
  13. package/dist/fastapi-middleware.js +87 -0
  14. package/dist/fastapi-middleware.js.map +1 -0
  15. package/dist/fastapi-portable.d.ts +9 -0
  16. package/dist/fastapi-portable.js +295 -0
  17. package/dist/fastapi-portable.js.map +1 -0
  18. package/dist/fastapi-raw-handler.d.ts +28 -0
  19. package/dist/fastapi-raw-handler.js +282 -0
  20. package/dist/fastapi-raw-handler.js.map +1 -0
  21. package/dist/fastapi-response.d.ts +13 -0
  22. package/dist/fastapi-response.js +150 -0
  23. package/dist/fastapi-response.js.map +1 -0
  24. package/dist/fastapi-route.d.ts +12 -0
  25. package/dist/fastapi-route.js +629 -0
  26. package/dist/fastapi-route.js.map +1 -0
  27. package/dist/fastapi-types.d.ts +39 -0
  28. package/dist/fastapi-types.js +5 -0
  29. package/dist/fastapi-types.js.map +1 -0
  30. package/dist/fastapi-utils.d.ts +16 -0
  31. package/dist/fastapi-utils.js +99 -0
  32. package/dist/fastapi-utils.js.map +1 -0
  33. package/dist/fastapi-websocket.d.ts +6 -0
  34. package/dist/fastapi-websocket.js +77 -0
  35. package/dist/fastapi-websocket.js.map +1 -0
  36. package/dist/generators/core.d.ts +23 -0
  37. package/dist/generators/core.js +906 -0
  38. package/dist/generators/core.js.map +1 -0
  39. package/dist/generators/data.d.ts +15 -0
  40. package/dist/generators/data.js +443 -0
  41. package/dist/generators/data.js.map +1 -0
  42. package/dist/generators/ground.d.ts +20 -0
  43. package/dist/generators/ground.js +333 -0
  44. package/dist/generators/ground.js.map +1 -0
  45. package/dist/generators/infra.d.ts +8 -0
  46. package/dist/generators/infra.js +109 -0
  47. package/dist/generators/infra.js.map +1 -0
  48. package/dist/index.d.ts +6 -0
  49. package/dist/index.js +7 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/ir-semantics/python-leg.d.ts +45 -0
  52. package/dist/ir-semantics/python-leg.js +291 -0
  53. package/dist/ir-semantics/python-leg.js.map +1 -0
  54. package/dist/python-stdlib-preamble.d.ts +32 -0
  55. package/dist/python-stdlib-preamble.js +86 -0
  56. package/dist/python-stdlib-preamble.js.map +1 -0
  57. package/dist/transpiler-fastapi.d.ts +8 -0
  58. package/dist/transpiler-fastapi.js +593 -0
  59. package/dist/transpiler-fastapi.js.map +1 -0
  60. package/dist/type-map.d.ts +14 -0
  61. package/dist/type-map.js +288 -0
  62. package/dist/type-map.js.map +1 -0
  63. package/package.json +37 -0
package/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # @kernlang/python
2
+
3
+ [![npm](https://img.shields.io/npm/v/@kernlang/python?color=cb3837&label=npm)](https://www.npmjs.com/package/@kernlang/python)
4
+ [![license](https://img.shields.io/badge/license-AGPL--3.0-blue)](https://github.com/KERNlang/kern/blob/main/LICENSE)
5
+
6
+ Kern FastAPI Python backend transpiler
7
+
8
+ Part of the [KERN monorepo](https://github.com/KERNlang/kern).
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ npm install @kernlang/python
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ```ts
19
+ import { transpileFastAPI } from '@kernlang/python';
20
+
21
+ const pythonCode = transpileFastAPI(kernSource);
22
+ ```
23
+
24
+ ## License
25
+
26
+ AGPL-3.0
@@ -0,0 +1,152 @@
1
+ /** Native KERN handler-body codegen — Python target (slices 1–3).
2
+ *
3
+ * Mirror of `packages/core/src/codegen/body-ts.ts` for the FastAPI/Python
4
+ * target. Walks the children of a handler with `lang=kern` and emits Python
5
+ * body lines. Recognized statements:
6
+ *
7
+ * - `let name=X value="EXPR"` — `X = EXPR` (slice 1)
8
+ * - `return value="EXPR"` / bare `return` (slice 1)
9
+ * - `if cond="EXPR"` / sibling `else` — `if EXPR:\n body\nelse:\n body` (slice 2c).
10
+ * - `while cond="EXPR"` — `while EXPR:\n body`
11
+ * - `for name=i from=0 to="List.length(xs)"` — `for i in range(...)`
12
+ * `else > if(…)` and `else > [if(…), else_inner]` collapse to `elif EXPR:` so
13
+ * raw `elif` chains round-trip byte-equivalent through slice 5b migration.
14
+ *
15
+ * Statement-level propagation `?` lowers to:
16
+ *
17
+ * __k_t1 = await call()
18
+ * if __k_t1.kind == 'err':
19
+ * return __k_t1
20
+ * u = __k_t1.value
21
+ *
22
+ * Slice 3 additions:
23
+ * - Body emit returns `{ code, imports }`. The generator uses the imports
24
+ * set to inject `import math` (etc.) at the top of the function body,
25
+ * so `Number.floor`/`ceil`/`round` lowerings work without surfacing
26
+ * a `NameError: math`.
27
+ * - `BodyEmitOptions.symbolMap` renames KERN identifiers to their
28
+ * Python-form equivalents at codegen time. The FastAPI generator builds
29
+ * a `userId → user_id` map from the param list so KERN bodies that
30
+ * reference `userId` resolve correctly against the snake_cased Python
31
+ * signature. Identifiers absent from the map pass through unchanged.
32
+ * - Optional-chain lowering for `member` (slice 3d): `a?.b` Python-lowers
33
+ * to `(a.b if a is not None else None)`. The receiver must be
34
+ * side-effect-free (ident or pure member chain); calls/awaits in the
35
+ * receiver throw with a let-bind hint to avoid double-evaluation.
36
+ *
37
+ * Indentation: Python is whitespace-significant, so the recursive walk
38
+ * threads a `indent` string. The propagation hoist embeds its own 4-space
39
+ * relative indent on the `return __k_tN` line; the wrapper prepends the
40
+ * surrounding indent so the post-emit result nests correctly. */
41
+ import type { IRNode, ValueIR } from '@kernlang/core';
42
+ /** Slice 3e — caller-provided options for the Python body emitter.
43
+ * Currently only `symbolMap`; future slices may add diagnostics, source-map
44
+ * hooks, or per-handler config. Keep this open-ended so 3a/3b/3d/future
45
+ * surface extensions can extend without breaking the call-site contract. */
46
+ export interface BodyEmitOptions {
47
+ /** Slice 3a — KERN-identifier → Python-identifier rename map. The FastAPI
48
+ * generator passes `userId → user_id` (etc.) so a body that references
49
+ * the KERN-form `userId` resolves to the snake_cased Python parameter.
50
+ * Identifiers not in the map pass through unchanged. */
51
+ symbolMap?: Record<string, string>;
52
+ /** Slice 4a review fix (Gemini #5) — how to lower the `?` propagation
53
+ * hoist's err-branch return:
54
+ * - 'value' (default for `fn`): `return __k_tN` so the caller sees
55
+ * the err Result and can chain. Matches slice 1 semantics.
56
+ * - 'http-exception' (FastAPI routes): `raise HTTPException(500,
57
+ * detail=__k_tN.error)` so route handlers don't accidentally
58
+ * return a 200 OK with an err body. The route emitter is
59
+ * responsible for adding `from fastapi import HTTPException`
60
+ * to the file's imports when this style is used.
61
+ * The route emitter walks `usedPropagation` in the result to know
62
+ * whether the import is actually required. */
63
+ propagateStyle?: 'value' | 'http-exception';
64
+ /**
65
+ * IR-semantics differential harness opt-in (PR-3b). When `eachIterNext`
66
+ * is true, the `each` loop emits a `_kern_trace({"op":"iter-next", ...})`
67
+ * call as the FIRST statement inside each iteration — symmetric with
68
+ * TS body-ts.ts. Production codegen never sets this. See
69
+ * packages/core/src/ir/semantics/python-leg.ts for the runtime contract.
70
+ */
71
+ traceHooks?: {
72
+ eachIterNext?: boolean;
73
+ };
74
+ }
75
+ /** Slice 3e — public return shape. `code` is the joined body text;
76
+ * `imports` is the per-handler set of import identifiers
77
+ * (e.g., `'math'` ⇒ `import math`) that the generator must emit at the
78
+ * top of the function body before the code.
79
+ *
80
+ * Slice 4a review fix — `usedPropagation` is true iff the body emitted at
81
+ * least one `?` propagation hoist. Callers using `propagateStyle:
82
+ * 'http-exception'` use this signal to decide whether to add `from
83
+ * fastapi import HTTPException` to the route file's imports.
84
+ *
85
+ * PR-4 — `helpers` carries runtime helper function definitions the body
86
+ * references (e.g. `_kern_pairs` / `_kern_async_pairs` for `each` pair-mode
87
+ * normalization). Consumers must emit each entry at module scope BEFORE the
88
+ * body's function definition so the helpers are in scope when the body
89
+ * runs. Set semantics give de-dup for free across multiple handlers in the
90
+ * same module. */
91
+ export interface BodyEmitResult {
92
+ code: string;
93
+ imports: Set<string>;
94
+ usedPropagation: boolean;
95
+ helpers: Set<string>;
96
+ }
97
+ /** PR-4 — Python helpers that normalize `each` pair-mode iteration sources.
98
+ * Co-located with the codegen so the production emitter and the differential
99
+ * harness use byte-identical definitions; consumers emit the string at module
100
+ * scope when `BodyEmitResult.helpers` is non-empty.
101
+ *
102
+ * Semantics:
103
+ * - `_kern_pairs(v)`: yields `(k, v)` tuples. Uses `v.items()` when present
104
+ * (Mapping shapes — dict, OrderedDict, custom Mapping subclasses); falls
105
+ * back to `iter(v)` so an iterable of `[k, v]` pairs (list/tuple) also
106
+ * destructures cleanly. Matches JS `for (const [k, v] of arrayOfPairs)`
107
+ * expressiveness — this is the divergence-1 fix from PR-3b audit.
108
+ * - `_kern_async_pairs(v)`: async generator. If `v` has `__aiter__` it
109
+ * forwards each item. Otherwise it falls back to `_kern_pairs(v)` so
110
+ * `async for` over a sync Mapping or array-of-pairs is well-defined —
111
+ * this is the divergence-2/3 fix (`async for` no longer requires an
112
+ * async iterable; sync data is wrapped at iteration entry).
113
+ *
114
+ * Both helpers are pure functions on the input; no captures, no globals. */
115
+ export declare const KERN_PAIR_HELPERS_PY: string;
116
+ /** Emit the body of a native KERN handler as Python source. Returns the
117
+ * joined body text. Each top-level line is unindented; nested `if`-bodies
118
+ * carry one level of 4-space indent per level of nesting.
119
+ *
120
+ * Legacy slice 1/2 signature — returns just the code string. Callers
121
+ * that also need the import set (slice 3b: `math` etc.) and/or want to
122
+ * pass a symbol map (slice 3a: `userId → user_id`) should use
123
+ * `emitNativeKernBodyPythonWithImports`.
124
+ *
125
+ * Slice 3 review fix (OpenCode + Gemini): if the handler requires imports
126
+ * (e.g. `Number.floor` ⇒ `math`) and the legacy entry point is used,
127
+ * the imports would be silently discarded — the generated Python would
128
+ * reference `__k_math.floor(...)` without the matching `import math as
129
+ * __k_math`, producing a `NameError` at runtime. Throw instead so the
130
+ * caller upgrades to the WithImports variant rather than shipping
131
+ * broken code. */
132
+ export declare function emitNativeKernBodyPython(handlerNode: IRNode, options?: BodyEmitOptions): string;
133
+ /** Slice 3e — context-aware variant returning `{ code, imports }`. The
134
+ * FastAPI generator uses this to inject `import math` (etc.) at the top
135
+ * of the function body and to pass the param-rename map (3a) so the body
136
+ * resolves correctly against the snake_cased Python signature.
137
+ *
138
+ * Slice 4a review fix — also returns `usedPropagation` so the route
139
+ * emitter can conditionally add `from fastapi import HTTPException`
140
+ * when `propagateStyle: 'http-exception'` is in effect. */
141
+ export declare function emitNativeKernBodyPythonWithImports(handlerNode: IRNode, options?: BodyEmitOptions): BodyEmitResult;
142
+ /** Slice-1 ValueIR → Python expression. Covers the surface that body-ts.ts
143
+ * emits today; later slices extend per the spec.
144
+ *
145
+ * Slice 3 — accepts an `options` bag so callers can supply a `symbolMap`
146
+ * (3a) without having to construct a `BodyEmitContext` directly. Imports
147
+ * are still collected during the walk but are not surfaced to the caller
148
+ * via this entry point — use `emitNativeKernBodyPythonWithImports` when
149
+ * you need the imports set. The internal recursive callers go through
150
+ * `emitPyExprCtx` which threads the live ctx (and therefore the live
151
+ * imports set) end-to-end. */
152
+ export declare function emitPyExpression(node: ValueIR, options?: BodyEmitOptions): string;