Skip to content

Native views

The boundary between PythonNative's element tree and concrete native widgets. Each commit's diff is expressed as a flat list of mutation ops referencing integer tags, applied through a single apply_mutations call on the process-wide view backend returned by get_backend. On device that backend is the BridgeBackend, which builds the wire commit once, serializes it once, and hands it to the renderer core over the native bridge; the core validates and lays it out and queues mount transactions for the Swift and Kotlin component managers. The browser preview uses the same backend with a WebSocket transport to the page. Headless tests install a FakeBackend, which commits to the host build of the core, with set_backend; there is no Python view-handler layer, and get_backend raises off device when no backend was installed.

The view backend the reconciler commits to.

The reconciler talks to exactly one object, obtained from get_backend, through a small protocol: apply_mutations (one ordered batch of create/update/insert/destroy ops per commit, see pythonnative.mutations), prepare_layout and compute_layout, resolve_view, command, and the animation hooks (set_animated_property, start_animation, cancel_animation). Two implementations exist, and both commit to the renderer core:

  • BridgeBackend (iOS, Android, and the browser preview): serializes each commit and hands it to the core, which lays it out and queues it for the platform's UI thread, where the Swift and Kotlin component managers, or the preview page's DOM managers, own every platform view. Python holds no native objects. resolve_view answers with a NativeViewRef.
  • FakeBackend (headless tests): the bridge backend over the host build of the core, plus an inspectable tree of fake views. Tests install one with set_backend.

Platform selection happens lazily on first use, so this package imports on any platform. Off device, with no backend installed, get_backend raises instead of guessing.

Modules:

Name Description
bridge_backend

The view backend that commits to the renderer core (RFC 0007).

Classes:

Name Description
BridgeBackend

Backend protocol implementation that commits to the renderer core.

NativeViewRef

Opaque handle to a native view living on the other side of the bridge.

Functions:

Name Description
get_backend

Return the process-wide view backend, creating the bridge backend on first use.

set_backend

Install a backend explicitly (tests), or pass None to reset the singleton.

parse_color_int

Parse a color value into a signed 32-bit ARGB int.

BridgeBackend

BridgeBackend(
    transport: Any = None, *, surface: int = SURFACE
)

Backend protocol implementation that commits to the renderer core.

Methods:

Name Description
prepare_layout

Include the layout request in the next commit when a viewport is known.

compute_layout

Lay out in the core without a commit, publishing changed frames.

subscribe_layout

Observe geometry without retaining an unmounted reconciler.

accept_layout

Accept geometry only for this surface's current committed revision.

measure_in_window

The view's frame in its screen's coordinates, read from the core's shadow tree.

resolve_view

Return the handle for tag (None if the view is gone).

type_of

Return the element type registered for tag.

live_view_count

Number of views in the core's shadow tree.

python_props

Props held Python-side for tag (callables never sent to native).

apply_mutations

Build, serialize, and commit ops to the core in one crossing.

surface_failed

The UI thread couldn't mount a transaction; the surface needs a remount.

defer_event

Keep input ordered until its commit and Python effects publish.

release_events

Deliver events after refs and effects have observed a successful commit.

accept_event

Reject events from destroyed views, earlier applications, and replayed input.

command

Queue a view command behind pending mounts; returns a future for its result.

accept_command_result

Resolve the future of a command the UI thread ran.

set_animated_property

Write one animated property value without animating.

install_animation_graph

Install expression nodes and view bindings on the UI thread.

start_animation

Start a driver on the UI thread; returns whether the core accepted the request.

cancel_animation

Stop a driver; its value arrives with the animation message that reports the cancellation.

reset

Forget a disconnected surface before the host remounts its tree.

Attributes:

Name Type Description
native_layout

Layout always runs in the core; there is no Python layout engine.

selective_layout

Ask the core for observed frames only (tests ask for every frame).

transport Any

The transport in use (resolved lazily on first access).

native_layout class-attribute instance-attribute

native_layout = True

Layout always runs in the core; there is no Python layout engine.

selective_layout class-attribute instance-attribute

selective_layout = True

Ask the core for observed frames only (tests ask for every frame).

transport property

transport: Any

The transport in use (resolved lazily on first access).

prepare_layout

prepare_layout(
    roots: list[int], width: float, height: float
) -> None

Include the layout request in the next commit when a viewport is known.

compute_layout

compute_layout(
    roots: list[int], width: float, height: float
) -> None

Lay out in the core without a commit, publishing changed frames.

subscribe_layout

subscribe_layout(callback: Any) -> None

Observe geometry without retaining an unmounted reconciler.

accept_layout

accept_layout(payload: Any) -> None

Accept geometry only for this surface's current committed revision.

measure_in_window async

measure_in_window(
    tag: int,
) -> Optional[tuple[float, float, float, float]]

The view's frame in its screen's coordinates, read from the core's shadow tree.

resolve_view

resolve_view(tag: int) -> Optional[NativeViewRef]

Return the handle for tag (None if the view is gone).

type_of

type_of(tag: int) -> Optional[str]

Return the element type registered for tag.

live_view_count

live_view_count() -> int

Number of views in the core's shadow tree.

python_props

python_props(tag: int) -> Dict[str, Any]

Props held Python-side for tag (callables never sent to native).

apply_mutations

apply_mutations(
    ops: Sequence[Mutation],
) -> Future[None] | None

Build, serialize, and commit ops to the core in one crossing.

A TextInput value update echoes the last edit revision the native side reported, so native can discard a stale value that raced a newer keystroke.

surface_failed

surface_failed(payload: Any) -> None

The UI thread couldn't mount a transaction; the surface needs a remount.

defer_event

defer_event(tag: int, name: str, envelope: Any) -> bool

Keep input ordered until its commit and Python effects publish.

release_events

release_events() -> None

Deliver events after refs and effects have observed a successful commit.

accept_event

accept_event(tag: int, name: str, envelope: Any) -> bool

Reject events from destroyed views, earlier applications, and replayed input.

command

command(
    tag: int,
    name: str,
    args: Optional[Dict[str, Any]] = None,
) -> Future[Any]

Queue a view command behind pending mounts; returns a future for its result.

Fire-and-forget commands (focus, scroll_to_offset) can ignore the future; await it for commands that answer (get_value, get_scroll_offset).

Raises:

Type Description
CommitError

When tag is stale, isn't mounted, or the core rejects the command's arguments.

accept_command_result

accept_command_result(payload: Any) -> None

Resolve the future of a command the UI thread ran.

set_animated_property

set_animated_property(
    tag: int, prop_name: str, value: Any
) -> None

Write one animated property value without animating.

install_animation_graph

install_animation_graph(
    tag: int, graph: dict[str, Any]
) -> None

Install expression nodes and view bindings on the UI thread.

start_animation

start_animation(
    tag: int,
    anim_id: int,
    prop_name: str,
    spec: Dict[str, Any],
) -> bool

Start a driver on the UI thread; returns whether the core accepted the request.

cancel_animation

cancel_animation(tag: int, anim_id: int) -> None

Stop a driver; its value arrives with the animation message that reports the cancellation.

reset

reset() -> None

Forget a disconnected surface before the host remounts its tree.

NativeViewRef

NativeViewRef(tag: int, type_name: str)

Opaque handle to a native view living on the other side of the bridge.

Attributes:

Name Type Description
tag

The reconciler-assigned tag; pass it to Reconciler.dispatch_command or get_backend().command.

type_name

The element type ("Text", "ScrollView", ...).

get_backend

get_backend() -> Any

Return the process-wide view backend, creating the bridge backend on first use.

Raises:

Type Description
RuntimeError

Off device when no backend was installed with set_backend.

set_backend

set_backend(backend: Any) -> None

Install a backend explicitly (tests), or pass None to reset the singleton.

Parameters:

Name Type Description Default
backend Any

The replacement backend, or None to clear so the next get_backend call rebuilds the platform backend.

required

parse_color_int

parse_color_int(color: Union[str, int]) -> int

Parse a color value into a signed 32-bit ARGB int.

Accepts "#RRGGBB", "#AARRGGBB", or a raw integer. Java APIs such as setBackgroundColor expect a signed 32-bit int, so values with a high alpha byte (0xFF......) become their negative two's-complement equivalent. Kept for extension authors writing Python-side color plumbing; the renderers parse colors natively.

Parameters:

Name Type Description Default
color Union[str, int]

Hex string (with or without leading #) or an int.

required

Returns:

Type Description
int

Signed 32-bit ARGB int suitable for Android's color APIs.

Mutation ops

The op types themselves are documented in Mutation ops.

Event routing

The registry and its dispatch entry point are documented in Events.

On-device backend

The view backend that commits to the renderer core (RFC 0007).

Each commit is built as wire operations once, serialized once, and handed to the core, which validates it, applies it to its shadow tree, lays it out, and queues the mount for the platform's UI thread. The acknowledgement arrives when the core has accepted and laid out the commit, before widgets exist; commands and animation requests issued afterward queue behind that mount, so they always reach the widgets it creates. Rejected commits leave the surface as it was; a failed mount poisons it until it is remounted.

Native events carry application, revision, sequence, and text edit identities. NativeViewRef holds a live native tag rather than a UI object.

Classes:

Name Description
CommitError

A malformed, stale, or failed native transaction.

NativeViewRef

Opaque handle to a native view living on the other side of the bridge.

BridgeBackend

Backend protocol implementation that commits to the renderer core.

Attributes:

Name Type Description
SURFACE

The surface every host mounts into; the core supports more, hosts use one.

SURFACE module-attribute

SURFACE = 1

The surface every host mounts into; the core supports more, hosts use one.

CommitError

Bases: RuntimeError

A malformed, stale, or failed native transaction.

NativeViewRef

NativeViewRef(tag: int, type_name: str)

Opaque handle to a native view living on the other side of the bridge.

Attributes:

Name Type Description
tag

The reconciler-assigned tag; pass it to Reconciler.dispatch_command or get_backend().command.

type_name

The element type ("Text", "ScrollView", ...).

BridgeBackend

BridgeBackend(
    transport: Any = None, *, surface: int = SURFACE
)

Backend protocol implementation that commits to the renderer core.

Methods:

Name Description
prepare_layout

Include the layout request in the next commit when a viewport is known.

compute_layout

Lay out in the core without a commit, publishing changed frames.

subscribe_layout

Observe geometry without retaining an unmounted reconciler.

accept_layout

Accept geometry only for this surface's current committed revision.

measure_in_window

The view's frame in its screen's coordinates, read from the core's shadow tree.

resolve_view

Return the handle for tag (None if the view is gone).

type_of

Return the element type registered for tag.

live_view_count

Number of views in the core's shadow tree.

python_props

Props held Python-side for tag (callables never sent to native).

apply_mutations

Build, serialize, and commit ops to the core in one crossing.

surface_failed

The UI thread couldn't mount a transaction; the surface needs a remount.

defer_event

Keep input ordered until its commit and Python effects publish.

release_events

Deliver events after refs and effects have observed a successful commit.

accept_event

Reject events from destroyed views, earlier applications, and replayed input.

command

Queue a view command behind pending mounts; returns a future for its result.

accept_command_result

Resolve the future of a command the UI thread ran.

set_animated_property

Write one animated property value without animating.

install_animation_graph

Install expression nodes and view bindings on the UI thread.

start_animation

Start a driver on the UI thread; returns whether the core accepted the request.

cancel_animation

Stop a driver; its value arrives with the animation message that reports the cancellation.

reset

Forget a disconnected surface before the host remounts its tree.

Attributes:

Name Type Description
native_layout

Layout always runs in the core; there is no Python layout engine.

selective_layout

Ask the core for observed frames only (tests ask for every frame).

transport Any

The transport in use (resolved lazily on first access).

native_layout class-attribute instance-attribute

native_layout = True

Layout always runs in the core; there is no Python layout engine.

selective_layout class-attribute instance-attribute

selective_layout = True

Ask the core for observed frames only (tests ask for every frame).

transport property

transport: Any

The transport in use (resolved lazily on first access).

prepare_layout

prepare_layout(
    roots: list[int], width: float, height: float
) -> None

Include the layout request in the next commit when a viewport is known.

compute_layout

compute_layout(
    roots: list[int], width: float, height: float
) -> None

Lay out in the core without a commit, publishing changed frames.

subscribe_layout

subscribe_layout(callback: Any) -> None

Observe geometry without retaining an unmounted reconciler.

accept_layout

accept_layout(payload: Any) -> None

Accept geometry only for this surface's current committed revision.

measure_in_window async

measure_in_window(
    tag: int,
) -> Optional[tuple[float, float, float, float]]

The view's frame in its screen's coordinates, read from the core's shadow tree.

resolve_view

resolve_view(tag: int) -> Optional[NativeViewRef]

Return the handle for tag (None if the view is gone).

type_of

type_of(tag: int) -> Optional[str]

Return the element type registered for tag.

live_view_count

live_view_count() -> int

Number of views in the core's shadow tree.

python_props

python_props(tag: int) -> Dict[str, Any]

Props held Python-side for tag (callables never sent to native).

apply_mutations

apply_mutations(
    ops: Sequence[Mutation],
) -> Future[None] | None

Build, serialize, and commit ops to the core in one crossing.

A TextInput value update echoes the last edit revision the native side reported, so native can discard a stale value that raced a newer keystroke.

surface_failed

surface_failed(payload: Any) -> None

The UI thread couldn't mount a transaction; the surface needs a remount.

defer_event

defer_event(tag: int, name: str, envelope: Any) -> bool

Keep input ordered until its commit and Python effects publish.

release_events

release_events() -> None

Deliver events after refs and effects have observed a successful commit.

accept_event

accept_event(tag: int, name: str, envelope: Any) -> bool

Reject events from destroyed views, earlier applications, and replayed input.

command

command(
    tag: int,
    name: str,
    args: Optional[Dict[str, Any]] = None,
) -> Future[Any]

Queue a view command behind pending mounts; returns a future for its result.

Fire-and-forget commands (focus, scroll_to_offset) can ignore the future; await it for commands that answer (get_value, get_scroll_offset).

Raises:

Type Description
CommitError

When tag is stale, isn't mounted, or the core rejects the command's arguments.

accept_command_result

accept_command_result(payload: Any) -> None

Resolve the future of a command the UI thread ran.

set_animated_property

set_animated_property(
    tag: int, prop_name: str, value: Any
) -> None

Write one animated property value without animating.

install_animation_graph

install_animation_graph(
    tag: int, graph: dict[str, Any]
) -> None

Install expression nodes and view bindings on the UI thread.

start_animation

start_animation(
    tag: int,
    anim_id: int,
    prop_name: str,
    spec: Dict[str, Any],
) -> bool

Start a driver on the UI thread; returns whether the core accepted the request.

cancel_animation

cancel_animation(tag: int, anim_id: int) -> None

Stop a driver; its value arrives with the animation message that reports the cancellation.

reset

reset() -> None

Forget a disconnected surface before the host remounts its tree.

Component managers

The native implementations live in the templates: PythonNativeKit/Sources/PythonNativeKit/Components (Swift) and pythonnative/src/main/java/com/pythonnative/runtime/components (Kotlin). Their hooks are described in Native views (concept).

Next steps