Skip to content

Diagnostics

Developer-mode warnings and error reporting. This module powers the feedback you get while developing: [PN] WARN messages for suspicious props and styles, the HookOrderError raised on conditional hooks, and the RedBox overlay that surfaces uncaught errors from renders, effects, and event handlers.

Dev mode is enabled automatically by pn preview and by pn run --hot-reload, or explicitly with the PN_DEV=1 environment variable. In production builds every check in this module is skipped, so shipping apps pay no overhead.

import pythonnative as pn

if pn.diagnostics.is_dev():
    pn.diagnostics.warn("fetching from a staging endpoint")

Most apps never call this module directly; it exists so framework code (and custom component libraries) can report problems in a way that reaches the developer instead of disappearing into a log.

Developer diagnostics: dev mode, warnings, and error reporting.

PythonNative distinguishes dev mode (the pn preview window, pn run with hot reload, or any process with PN_DEV=1) from production. Dev mode turns on:

  • Validation warnings (warn / warn_once): unknown style keys, duplicate list keys, and similar mistakes are printed once with a suggestion instead of failing silently.
  • Hook-order checking: calling hooks conditionally corrupts slot state; in dev mode the mismatch raises a HookOrderError immediately instead of cross-wiring state.
  • The RedBox: uncaught errors from render, effects, and event handlers are routed to the screen host, which presents a full-screen error overlay (see pythonnative.screen) instead of crashing or swallowing the traceback.

In production none of this runs: validation is skipped, hook-order checks are skipped, and errors propagate exactly as raised.

This module has no dependencies on the rest of PythonNative, so any module (hooks, reconciler, events) may import it freely.

Classes:

Name Description
HookOrderError

Raised in dev mode when hooks are called in a different order than the previous render.

Functions:

Name Description
set_dev_mode

Explicitly enable or disable dev mode for this process.

is_dev

Return whether dev diagnostics are active.

warn

Print a dev warning and record it in the warning log.

warn_once

Like warn, but at most once per key.

get_warnings

Return a snapshot of the recorded warnings (oldest first).

clear_warnings

Drop all recorded warnings and dedupe keys (test helper).

set_error_reporter

Register or unregister owner's RedBox reporter.

report_error

Route exc to the active RedBox reporter (dev mode only).

HookOrderError

Bases: RuntimeError

Raised in dev mode when hooks are called in a different order than the previous render.

Hooks map to state slots by call order, so calling them inside conditionals or loops (or returning early between hook calls) silently cross-wires state in production. Dev mode detects the mismatch and raises this error with the offending component and slot so the bug is caught at the source.

set_dev_mode

set_dev_mode(enabled: bool) -> None

Explicitly enable or disable dev mode for this process.

Called automatically by pn preview and by the screen host's enable_hot_reload (which the device templates invoke on debug builds). An explicit call wins over the PN_DEV environment variable.

Parameters:

Name Type Description Default
enabled bool

True to turn on dev diagnostics.

required

is_dev

is_dev() -> bool

Return whether dev diagnostics are active.

Resolution order: an explicit set_dev_mode call, then the PN_DEV environment variable, then False.

warn

warn(message: str) -> None

Print a dev warning and record it in the warning log.

No-op in production. Warnings are prefixed with [PN] WARN on stderr and retained (most recent 200) for inspection via get_warnings.

Parameters:

Name Type Description Default
message str

Human-readable description of the problem, ideally with a suggestion for the fix.

required

warn_once

warn_once(message: str, key: Optional[str] = None) -> None

Like warn, but at most once per key.

Use for per-render validation (style keys, list keys) so a warning fires once instead of sixty times a second.

Parameters:

Name Type Description Default
message str

The warning message.

required
key Optional[str]

Dedupe key, e.g. "style:Text:font_siez". Defaults to the message itself.

None

get_warnings

get_warnings() -> List[str]

Return a snapshot of the recorded warnings (oldest first).

clear_warnings

clear_warnings() -> None

Drop all recorded warnings and dedupe keys (test helper).

set_error_reporter

set_error_reporter(owner: Any, reporter: Optional[Callable[[BaseException, str], None]]) -> None

Register or unregister owner's RedBox reporter.

Parameters:

Name Type Description Default
owner Any

Any object identifying the registration (a screen host); keyed by id(owner).

required
reporter Optional[Callable[[BaseException, str], None]]

reporter(exc, phase) callable, or None to unregister the owner's reporter.

required

report_error

report_error(exc: BaseException, phase: str = 'runtime') -> bool

Route exc to the active RedBox reporter (dev mode only).

Parameters:

Name Type Description Default
exc BaseException

The exception to display.

required
phase str

Where it came from: "render", "effect", "event", or "async".

'runtime'

Returns:

Type Description
bool

True when a reporter accepted the error, False when no

bool

reporter is registered (or dev mode is off), in which case the

bool

caller should fall back to its default behavior.

Next steps