simvx.core.py_console

PyConsoleNode – an in-process Python REPL that speaks the TerminalEmulator contract.

Where ShellNode wraps an OS subprocess (and needs a real PTY for line editing), PyConsoleNode runs an interactive interpreter inside the running app. It exposes the same duck-typed surface a TerminalEmulator attaches to – stdout_data / stderr_data / process_exited signals plus write() / start() / stop() / resize() – so the same widget drives either backend.

Because it is in-process it works identically on desktop and in the browser (Pyodide), where no subprocess or pty device exists. It also shares the host interpreter, so the namespace can expose live objects (the scene tree, nodes) for debugging – something an external python3 subprocess cannot do.

The flip side of in-process execution: a command that blocks (input(), a long loop, time.sleep) blocks the frame loop. input() is therefore replaced with a clear error; long-running work is the caller’s responsibility.

Module Contents

Classes

PyConsoleNode

Interactive in-process Python REPL, attachable to a TerminalEmulator.

Data

log

API

simvx.core.py_console.log

‘getLogger(…)’

class simvx.core.py_console.PyConsoleNode(namespace: dict | None = None, *, banner: str | None = None, **kwargs)[source]

Bases: simvx.core.node.Node

Interactive in-process Python REPL, attachable to a TerminalEmulator.

Emits stdout_data(str) for results/prints and prompts, stderr_data(str) for tracebacks, and process_exited(int) when the console is closed (Ctrl-D on an empty line, exit(), or :meth:stop).

namespace seeds the interpreter globals; pass live objects here to inspect them from the console (e.g. {"root": my_scene}).

Initialization

property ps1: str[source]
property ps2: str[source]
property running: bool[source]
start(*_args)[source]

Print the banner and the first prompt.

stop()[source]

Close the console, emitting process_exited once.

resize(cols: int, _rows: int)[source]
write(data: str)[source]

Feed terminal keystrokes (raw chars + escape sequences) to the line editor.

on_exit_tree()[source]
strict_errors: ClassVar[bool]

True

dev_checks: ClassVar[bool]

None

script_error_raised

‘Signal(…)’

dynamic: bool

False

visible

‘Property(…)’

update_mode

‘Property(…)’

__properties__: ClassVar[dict[str, simvx.core.descriptors.Property]]

None

classmethod __init_subclass__(**kwargs)
property name: str
property visible_in_tree: bool
reset_error() None
add_child(node: simvx.core.node.T) simvx.core.node.T
remove_child(node: simvx.core.node.Node) None
reparent(new_parent: simvx.core.node.Node)
node_at(path, default=_NO_DEFAULT)
find(target, *, direct: bool = False)
find_all(target, *, direct: bool = False)
expect(target, *, direct: bool = False)
ancestor(target)
walk(*, include_self: bool = True) collections.abc.Iterator[simvx.core.node.Node]
property path: str
property is_scene_root: bool
add_to_group(group: str)
remove_from_group(group: str)
is_in_group(group: str) bool
on_ready() None
on_enter_tree() None
on_update(dt: float) None
on_fixed_update(dt: float) None
on_draw(renderer) None
on_picked(event: simvx.core.events.InputEvent) None
on_unhandled_input(event: simvx.core.events.TreeInputEvent) None
start_coroutine(gen: simvx.core.descriptors.Coroutine) simvx.core.descriptors.CoroutineHandle
stop_coroutine(gen_or_handle)
queue_redraw() None
property render_dirty: bool
clear_children()
destroy()
property destroying: bool
call_deferred(method: collections.abc.Callable[..., Any], *args: Any) None
property app
property tree: simvx.core.scene_tree.SceneTree
property physics
property physics_2d
__getitem__(key: str)
classmethod get_properties() dict[str, simvx.core.descriptors.Property]
__repr__()