@@ -173,14 +173,19 @@ All in `PM/commonTest`, so they run wherever the interpreter loads.
173173- ** U-8** A function on a Kotlin-named module carries Kotlin's own surface and nothing else: the
174174 Kotlin declaration name, keyword arguments by ** Kotlin parameter names** , Kotlin defaults for omitted
175175 parameters, overload sets under the base name, and its signature as public metadata
176- (` inspect.signature ` , ` python_multiplatform.describe ` ; contract in ` KotlinSurface.kt ` 's KDoc). No
176+ (` inspect.signature ` , ` python_multiplatform.describe ` ; contract in ` KotlinSurface.kt ` 's KDoc).
177+ ` describe(module, name) ` describes any bound name, a named constant (` STATIC_GETTER ` ) included,
178+ without evaluating it (#36 ). A module's ` dir() ` lists its direct child packages/objects and reading
179+ one as an attribute imports it (#35 ) — Kotlin names only. No
177180 member or parameter is renamed; the binder creates no ` pythonx ` module and a real ` pythonx ` package
178181 on disk is what ` import pythonx ` loads. The answer is the same whichever installer
179182 (` PythonProxySource ` , ` PythonxAdapter ` ) ran first for a table. ` Status: implemented ` on desktop —
180- ` PM/desktopTest/.../pythonx/KotlinNamedSurfaceTest.kt ` , ` ksp-fixtures/compose/.../KotlinSignatureMetadataTest.kt ` .
183+ ` PM/desktopTest/.../pythonx/KotlinNamedSurfaceTest.kt ` , ` BinderNamespaceTest.kt ` , ` ksp-fixtures/compose/.../KotlinSignatureMetadataTest.kt ` .
181184- ** U-9** A Pythonic package can serve extra member names on a Kotlin proxy through one hook,
182185 ` python_multiplatform.binding.add_member_resolver(fn) ` , `fn(kotlin_type_name, requested_name,
183- kotlin_member_names) -> kotlin_name | None`, asked only when no Kotlin member of that name exists.
186+ kotlin_member_names) -> kotlin_name | (kotlin_name, keyword_map) | None`, asked when no Kotlin member
187+ of that name exists — and, for a Kotlin-named member, only when a call passes keywords and only for
188+ its ` {python_kw: kotlinParam} ` keyword map (#34 ).
184189 The binder renames nothing itself (no resolver: ` AttributeError ` ), and aliases are cached in the
185190 registry, not written on the proxy class (` dir() ` stays Kotlin-only). Contract in ` KotlinSurface.kt ` 's
186191 KDoc. ` Status: implemented ` on desktop — ` PM/desktopTest/.../pythonx/MemberResolverTest.kt ` ,
@@ -211,6 +216,15 @@ All in `PM/commonTest`, so they run wherever the interpreter loads.
211216 ` ksp-fixtures/compose/src/desktopTest/ ` (` ComposableRenderTest.kt ` , ` M3ProofRenderTest.kt ` ,
212217 ` CallbackDrivenRenderTest.kt ` , pointer/drag render tests), ` GP/artifact/ComposableBindingTest.kt ` ;
213218 ` planned ` on Android, iOS and wasm.
219+ - ** B-8** A host draws a Python-declared application root with
220+ ` python.multiplatform.compose.PythonContent(root: PyObject) ` or ` PythonContent(module, attribute) ` ,
221+ from the ` python-multiplatform-compose ` module (` python-multiplatform ` itself does not depend on
222+ Compose). The root is a Python callable, or a Compose ` State ` that Python holds whose value is that
223+ callable. The state is read inside the composition, so a Python write into it replaces the root on
224+ the next frame with no host call; Python callables a root passed into composables are released when
225+ that root is replaced or the composition is disposed. The entry point names no library.
226+ ` Status: implemented ` on desktop — ` ksp-fixtures/compose/.../PythonContentRenderTest.kt ` ; the module
227+ compiles for Android, nothing runs there yet.
214228- ** B-7** The plugin generates ` .pyi ` stubs for the Kotlin-named modules only, under Kotlin names
215229 (keyword parameters by Kotlin name, ` = ... ` for a Kotlin default, receiver positional-only). Types are
216230 the declared Kotlin types: one stub class per bound type in the module of its own package, ` Dp | float `
@@ -262,6 +276,12 @@ All in `PM/commonTest`, so they run wherever the interpreter loads.
262276- ** N-3** Binding Kotlin/Native klib declarations at run time (B-2). ` Status: planned ` .
263277- ** N-4** Linux and Windows desktop runs in CI (P-2). ` Status: planned ` .
264278- ** N-5** Native-image upcall verification as an automated test (U-6). ` Status: planned ` .
279+ - ** N-6** Compose state created and written from Python through the binder:
280+ ` androidx.compose.runtime.mutableStateOf(x) ` callable, and ` .value ` of the returned ` MutableState `
281+ readable and writable on its proxy. Neither is bound today: the walker emits only ` FUNCTION ` and
282+ ` STATIC_GETTER ` entries (no instance members), and declines every declaration whose signature
283+ mentions a type parameter. B-8's test writes its root state through a fixture-local KSP-bound
284+ setter instead. ` Status: planned ` .
265285
266286---
267287
0 commit comments