simvx.core.scene_io.detection

Scene-file detection helpers — recognise SimVX scene scripts and modules.

These predicates use stdlib ast for speed and parser-version stability; parso is unnecessary for the structural checks they perform. The recognised Node base-class names are listed in :data:_NODE_BASE_CLASSES; any class whose direct base name is in that set qualifies as a Node subclass for detection purposes.

A scene file/module exposes exactly one Node subclass that either defines __init__ or declares at least one Property(...) descriptor at class scope. Multiple Node subclasses raise :class:AmbiguousSceneError from

func:

primary_node_class_from_source; :func:is_scene_path instead returns False so callers can use it as a cheap filesystem filter without exception handling.

Module Contents

Functions

is_scene_path

Return True iff path is a SimVX scene script or module folder.

primary_node_class_from_source

Return the single Node subclass name in source, else None.

has_procedural_construction

Return True iff a scene class builds children procedurally.

Data

API

simvx.core.scene_io.detection.__all__

[‘AmbiguousSceneError’, ‘has_procedural_construction’, ‘is_scene_path’, ‘primary_node_class_from_sou…

exception simvx.core.scene_io.detection.AmbiguousSceneError[source]

Bases: ValueError

Raised when a scene source contains more than one Node subclass.

Detection treats this as a user error rather than a missing-detection case: the editor cannot pick a primary class on the user’s behalf and must surface a remediation message (“split into separate files, or promote one class to the top-level scene”).

Initialization

Initialize self. See help(type(self)) for accurate signature.

class __cause__
class __context__
__delattr__()
__dir__()
__eq__()
__format__()
__ge__()
__getattribute__()
__getstate__()
__gt__()
__hash__()
__le__()
__lt__()
__ne__()
__new__()
__reduce__()
__reduce_ex__()
__repr__()
__setattr__()
__setstate__()
__sizeof__()
__str__()
__subclasshook__()
class __suppress_context__
class __traceback__
add_note()
class args
with_traceback()
simvx.core.scene_io.detection.is_scene_path(path: str | pathlib.Path) bool[source]

Return True iff path is a SimVX scene script or module folder.

A file qualifies when it parses as Python and exposes exactly one Node-derived class with either __init__ or one or more Property(...) descriptors. Multiple Node subclasses → False (the file is ambiguous; use :func:primary_node_class_from_source if a precise diagnostic is needed).

A folder qualifies when either folder/__init__.py or — if that file is missing or has no qualifying class — folder/<folder_name>.py qualifies under the same rule.

Returns False for non-existent paths, parse errors, multi-class files, or files with no qualifying class. Never raises.

simvx.core.scene_io.detection.primary_node_class_from_source(source: str, *, path: pathlib.Path | None = None) str | None[source]

Return the single Node subclass name in source, else None.

A class qualifies when it inherits a recognised Node base (see

Data:

_NODE_BASE_CLASSES) and either defines __init__ or exposes at least one class-body Property(...) assignment. With multiple qualifying classes, raises :class:AmbiguousSceneError; with zero, returns None.

path is used only to enrich error messages.

simvx.core.scene_io.detection.has_procedural_construction(source: str, class_name: str | None = None) bool[source]

Return True iff a scene class builds children procedurally.

A class is procedural when its __init__ body — or a method it calls — contains an add_child(...) invocation nested inside for, while, or if control flow. Such trees cannot be safely diff-reconciled by the round-trip layer; the editor should fall back to a greenfield overwrite (with a warning) for these.

With class_name=None, every Node subclass in the source is checked and True is returned if any is procedural. Malformed source returns True — the safer default for a tool that gates whether edits are reversible.