Skip to content

Re-export every manifest module by one rule over the binder's Kotlin-named surface #8

Closed

Description

@b-re-w

What

One mechanism that makes each pythonx.compose.* module in pythonx-map.toml a Pythonic view of its androidx.compose.* module, plus a test harness that installs the binder the way an embedder does now (no register_package).

Why

The binder exposes Kotlin names only and publishes a contract for exactly this (PythonMultiplatform d00f413f, KotlinSurface.kt): inspect.signature(fn) with Kotlin parameter names and KOTLIN_DEFAULT, and python_multiplatform.describe(fn). AGENTS.md §12–13: rename here, by rule, no per-widget wrapper. The 37 failing tests call the removed register_package.

Proposed API (to be refined in the PR)

  • pythonx/compose/_reexport.py holds the rule; each mapped package's __init__.py is one line that hands its module and Kotlin package to it, and gets a module __getattr__ / __dir__.
  • Names: a type or @Composable (PascalCase) keeps its Kotlin name; a camelCase function or property is reached by its snake_case name (fill_max_width → fillMaxWidth). The inverse is looked up in the module's real names, never computed, so toURLString stays reachable.
  • Keywords: on_click= → onClick=, mapped against the declaration's own parameter names from describe() (all overloads), so a keyword that matches no parameter is an error naming the valid ones.
  • Signatures: each re-exported callable answers inspect.signature with the snake_case names; defaults stay KOTLIN_DEFAULT.
  • Overloads: passed through; the binder dispatches.
  • Receiver methods: extension methods on returned proxies (Modifier.padding(16).fill_max_width()) resolve by the same rule.
  • Value classes: the manifest's raw-primitive-allowed is applied through python_multiplatform.binding.allow_raw_primitive when the package is imported.

Done when

  • tests/adapter.py no longer calls register_package; it installs python_multiplatform + python_multiplatform.binding from the binder source and imports pythonx.compose.* from disk.
  • The 37 tests pass with a PythonMultiplatform checkout (rewritten to the snake_case surface where they used the old one), and still skip without one.
  • A test fails when the rule is disabled (AGENTS.md §8).

Activity

  1. b-re-w commented on Oct 2, 2026

    @b-re-w
    MemberAuthor

    Landed in develop via #21 (module level). Receiver methods continue in #20.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions