@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.
- package/LICENSE +678 -0
- package/README.md +26 -0
- package/dist/codegen-body-python.d.ts +152 -0
- package/dist/codegen-body-python.js +1648 -0
- package/dist/codegen-body-python.js.map +1 -0
- package/dist/codegen-helpers.d.ts +21 -0
- package/dist/codegen-helpers.js +352 -0
- package/dist/codegen-helpers.js.map +1 -0
- package/dist/codegen-python.d.ts +17 -0
- package/dist/codegen-python.js +106 -0
- package/dist/codegen-python.js.map +1 -0
- package/dist/fastapi-middleware.d.ts +8 -0
- package/dist/fastapi-middleware.js +87 -0
- package/dist/fastapi-middleware.js.map +1 -0
- package/dist/fastapi-portable.d.ts +9 -0
- package/dist/fastapi-portable.js +295 -0
- package/dist/fastapi-portable.js.map +1 -0
- package/dist/fastapi-raw-handler.d.ts +28 -0
- package/dist/fastapi-raw-handler.js +282 -0
- package/dist/fastapi-raw-handler.js.map +1 -0
- package/dist/fastapi-response.d.ts +13 -0
- package/dist/fastapi-response.js +150 -0
- package/dist/fastapi-response.js.map +1 -0
- package/dist/fastapi-route.d.ts +12 -0
- package/dist/fastapi-route.js +629 -0
- package/dist/fastapi-route.js.map +1 -0
- package/dist/fastapi-types.d.ts +39 -0
- package/dist/fastapi-types.js +5 -0
- package/dist/fastapi-types.js.map +1 -0
- package/dist/fastapi-utils.d.ts +16 -0
- package/dist/fastapi-utils.js +99 -0
- package/dist/fastapi-utils.js.map +1 -0
- package/dist/fastapi-websocket.d.ts +6 -0
- package/dist/fastapi-websocket.js +77 -0
- package/dist/fastapi-websocket.js.map +1 -0
- package/dist/generators/core.d.ts +23 -0
- package/dist/generators/core.js +906 -0
- package/dist/generators/core.js.map +1 -0
- package/dist/generators/data.d.ts +15 -0
- package/dist/generators/data.js +443 -0
- package/dist/generators/data.js.map +1 -0
- package/dist/generators/ground.d.ts +20 -0
- package/dist/generators/ground.js +333 -0
- package/dist/generators/ground.js.map +1 -0
- package/dist/generators/infra.d.ts +8 -0
- package/dist/generators/infra.js +109 -0
- package/dist/generators/infra.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/ir-semantics/python-leg.d.ts +45 -0
- package/dist/ir-semantics/python-leg.js +291 -0
- package/dist/ir-semantics/python-leg.js.map +1 -0
- package/dist/python-stdlib-preamble.d.ts +32 -0
- package/dist/python-stdlib-preamble.js +86 -0
- package/dist/python-stdlib-preamble.js.map +1 -0
- package/dist/transpiler-fastapi.d.ts +8 -0
- package/dist/transpiler-fastapi.js +593 -0
- package/dist/transpiler-fastapi.js.map +1 -0
- package/dist/type-map.d.ts +14 -0
- package/dist/type-map.js +288 -0
- package/dist/type-map.js.map +1 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @kernlang/python
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@kernlang/python)
|
|
4
|
+
[](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;
|