You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit b1ef413
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/INTENT.md
+18-1Lines changed: 18 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,6 +26,23 @@ CPython interpreter inside a Kotlin Multiplatform application so that:
26
26
written (`Greeter('Kotlin').greet(2)` in `sample/`).
27
27
3.**The same code runs on every target** a Kotlin Multiplatform app ships to: desktop JVM, Android,
28
28
iOS, Android native, and the web (wasm, experimental).
29
+
4.**The project's own Python is statically typed by default** (TypedPython). The maintainer's goal:
30
+
31
+
> "파이썬을 컴파일 언어 및 타입 안정화, 정적 타입 검사, 컴파일 타임 타입검사를 지원할 수 있도록"
32
+
> — *Support Python as a compiled language with type stability, static type checking and
33
+
> compile-time type checking*, so that Python stays usable as AI-friendly languages such as Rust
34
+
> and TypeScript gain ground.
35
+
36
+
> "TypedPython을 별도 레포가 아니라 PythonMultiplatform의 기본 동작이 될거야"
37
+
> — *TypedPython is not a separate repository; it will be PythonMultiplatform's default behaviour.*
38
+
39
+
The maintainer chose the scope "검사만 기본, 컴파일은 opt-in" (2026-10-02): every user Python source
40
+
is **checked** by default; **compiling** it to native code is opt-in. The compiled code still runs on
41
+
the embedded CPython, as an extension module (`docs/design/typedpython.md`).
42
+
43
+
> The maintainer also asked to *explore* GPU kernels written in Python without a separate language
44
+
> ("GPU 관련 최적화까지도 별도 언어 없이 지원할 방안을 모색해보자"). That is an exploration, not yet
45
+
> a commitment; it is recorded in the design note only.
29
46
30
47
The CPython version moved on from 3.13 (the build pins 3.14.x today and offers opt-in free-threaded 3.14t builds
31
48
on desktop only); the intent — embed **CPython itself**, not a re-implementation — is unchanged.
@@ -88,7 +105,7 @@ no per-platform Python → Kotlin binding code to maintain.
88
105
| A replacement for the `pythonx` packages | §2.3 — they are real packages in their own repository |
89
106
| Runtime-reflection or name-lookup based binding | §2.1 — impossible under Kotlin/Native and native image |
90
107
| A hand-written wrapper per Kotlin function or class | Generic adaptation plus generated tables; per-declaration wrappers were tried in 2024 and rotted (`docs/archive/pythonx-adapter-design.md`) |
91
-
| A Python re-implementation, transpiler, or JVM-hosted Python | It embeds CPython itself, so C extensions keep working |
108
+
| A Python re-implementation, transpiler, or JVM-hosted Python | It embeds CPython itself, so C extensions keep working. TypedPython (§1.4) does not change this: checked code is ordinary Python, and compiled code is a CPython extension module, not a translation to another runtime|
92
109
| A build tool, dependency resolver or packager | That is pypackpack (the work) and toolchain (the Gradle vocabulary) |
93
110
| A sub-interpreter parallelism model | Rejected: extensions that do not declare multi-interpreter support fail to import; parallelism comes from free-threaded CPython |
94
111
| A vendored interpreter | The build downloads and verifies CPython per platform |
`explicit-any`) and any user-code expression of type `Any` outside `cast()` (`any-flow`) as errors;
324
+
the forbidden list (`eval`/`exec`, computed-name `getattr`/`setattr`/`delattr`, patching an imported
325
+
module or a module-level class, rebinding an unannotated name to a different type, and a list/set/dict
326
+
display whose inferred element type is a union) as warnings in `checked` mode and errors in
327
+
`compiled` mode. Nothing
328
+
inside dependencies is reported. `python -m typedpython check` exits 0 / 1 / 2 for clean / errors /
329
+
tool failure. `Status: partial` — the gate is asserted by
330
+
`python-multiplatform-ksp/src/test/python/` (run with that module's `.venv`); it is **not yet run by the
331
+
build** (design §6 step 1b). Rebinding and mixed containers are found by a second Pyrefly pass over a
332
+
probed copy (design §6.1), which runs only when a file has a name assigned twice or a container
333
+
display; `for` targets and comprehension variables are not probed.
334
+
-**N-8** TypedPython compilation to C (INTENT §1.4; design §4.3; #41). `@compiled` (a builtin name, no
335
+
import — #42) and a first-line `# typedpython: compiled` mark functions; the compiler lowers them
336
+
through the typed IR (`typedpython/ir.py`) to C against the CPython C API and builds an extension with
337
+
the platform C compiler. Compiled functions return what CPython returns (IR contract: checked i64
338
+
with deopt to the interpreted function, Python floor division/modulo, exact int/float comparison,
339
+
CPython's exception types and messages; tracebacks are the one accepted difference). `Status: planned`.
340
+
-**N-9** TypedPython memory safety is proved on the IR before C is generated (#41; maintainer decision
341
+
2026-10-03). Each property, and what happens when it cannot be proved:
342
+
343
+
| Property proved on the IR | If not proved |
344
+
|---|---|
345
+
| No local read before assignment on every path | function not compiled; diagnostic names the local |
346
+
| Every node's operand types match; no implicit conversion | not compiled; diagnostic |
347
+
| No deopting node in an impure function | not compiled; diagnostic |
348
+
| Array access in bounds, or a runtime bounds check kept | the check stays (never an unchecked access) |
349
+
| Array parameters only indexed, stored, `len`-ed; no aliasing (entry guard) | not compiled; diagnostic |
350
+
| OBJ references follow one ownership rule; no IR form for free, borrowed alias or NULL read | not compiled; diagnostic |
351
+
| Integer overflow checked and promoted (deopt); an op marked `proven` must re-prove its interval fits i64 | not compiled; diagnostic `verify/proven-overflow`|
352
+
|`Call.redo` only from an impure caller to a pure, may-deopt callee returning F64/BOOL/NONE | not compiled; diagnostic `verify/redo`|
353
+
|`entry_globals` only in a closed function (no user code runs); a call of a function with entry globals is a deopt point in its caller unless it is a legal redo or the caller snapshots the same globals | not compiled; diagnostic `verify/entry-global-open` / `verify/deopt-impure`|
354
+
355
+
Generated C reaches memory and `PyObject`s only through the runtime helpers. ASan/UBSan CI,
356
+
differential tests against the interpreter and fuzzing back the proof. `Status: planned`.
357
+
-**N-10** TypedPython incremental compilation (#41; maintainer decision 2026-10-03). The unit is a module.
358
+
Its cache key is the source hash, the interface hashes (typed signatures) of the modules it depends
359
+
on, the compiler version, the target platform and the build flags; a body-only change leaves the
360
+
interface hash unchanged, so dependent modules are not recompiled. C objects are cached per module.
361
+
The Gradle task declares exact inputs and outputs so up-to-date checks and the build cache apply.
362
+
Tests: changing one function body recompiles that module only; an unchanged rebuild spends ~0 s in
0 commit comments