simvx.core.scene_io.scene_file¶
High-level scene-shaped editing surface for parso-parsed sources.
This is Tier 3b of the scene I/O layer. It composes the lossless parse
(:mod:source_tree) and prefix-preserving primitives (:mod:edits) with
greenfield emission (:mod:emitter) and structural detection
(:mod:detection) into a small public API:
SceneFile — a parsed Python file with byte-perfect round-trip save.
SceneClass — an editable view of one Node-subclass in the file.
ImportSet — an editable view of the file's top-level imports.
The editor’s save/load path and the IDE’s refactor tools build on this surface. Lower tiers remain available for callers that need finer control.
Module Contents¶
Classes¶
A parsed Python scene file with byte-perfect round-trip save. |
|
An editable view of one Node-subclass class definition inside a scene. |
|
Editable view of the file’s top-level imports. |
Data¶
API¶
- simvx.core.scene_io.scene_file.__all__¶
[‘ImportSet’, ‘SceneClass’, ‘SceneFile’]
- class simvx.core.scene_io.scene_file.SceneFile(source_tree: simvx.core.scene_io.source_tree.SourceTree, *, path: pathlib.Path | None)[source]¶
A parsed Python scene file with byte-perfect round-trip save.
Holds a parso tree plus the original on-disk text. All edits operate on the parso tree; :meth:
savewritestree.get_code(). Round-trip identity is guaranteed when no edits were made.Initialization
- __slots__¶
(‘_source_tree’, ‘_path’, ‘_imports’, ‘_original_text’)
- classmethod load(path: str | pathlib.Path) simvx.core.scene_io.scene_file.SceneFile[source]¶
Read
pathand parse it.Raises :class:
FileNotFoundErrorwhen the file is absent;- Class:
parso.ParserSyntaxErrorfor malformed Python (we useerror_recovery=Falsefor explicit save targets so syntax issues surface immediately rather than silently producing a partial tree).
- classmethod from_source(text: str, *, path: pathlib.Path | None = None) simvx.core.scene_io.scene_file.SceneFile[source]¶
Parse already-loaded source
text.pathis recorded for :meth:saveand error messages but is not read.
- classmethod from_runtime(root: simvx.core.node.Node, *, class_name: str | None = None) simvx.core.scene_io.scene_file.SceneFile[source]¶
Greenfield: emit source for a live :class:
Nodetree, then parse it.The returned :class:
SceneFilehas nopathuntil :meth:saveis called with one.
- property path: pathlib.Path | None[source]¶
Path the file was loaded from / will be saved to, or
None.
- property source_tree: simvx.core.scene_io.source_tree.SourceTree[source]¶
Underlying lossless :class:
SourceTree.
- property imports: simvx.core.scene_io.scene_file.ImportSet[source]¶
Editable view of the file’s top-level imports.
- scene_class() simvx.core.scene_io.scene_file.SceneClass[source]¶
The single primary Node subclass in the file.
Raises :class:
AmbiguousSceneErrorif the file contains multiple Node subclasses; raises :class:ValueErrorif it contains none.
- all_scene_classes() list[simvx.core.scene_io.scene_file.SceneClass][source]¶
Every Node subclass defined in the file, in source order.
Used for diagnostics and IDE features. The typical scene has one. Detection mirrors :func:
primary_node_class_from_source’s rule (Node base +__init__or class-bodyPropertydescriptors).
- insert_top_level_class(name: str, base: str, *, body: str = 'pass', before: str | None = None) simvx.core.scene_io.scene_file.SceneClass[source]¶
Insert
class <name>(<base>): <body>at module scope.Auto-imports
basevia :class:ImportSet(defaults tosimvx.core). Placement is just before the existing scene class (or beforebeforewhen given) so the new definition sits between imports and the scene that uses it. Returns the new- Class:
SceneClassview.
Raises :class:
ValueErrorif a top-level class with the same name already exists.
- is_dirty() bool[source]¶
True iff :meth:
dumpdiffers from the original input text.Used by :class:
SceneModuleto skip writes for files that were opened but never edited.
- class simvx.core.scene_io.scene_file.SceneClass(file: simvx.core.scene_io.scene_file.SceneFile, class_node: parso.python.tree.Class)[source]¶
An editable view of one Node-subclass class definition inside a scene.
Initialization
- __slots__¶
(‘_file’, ‘_class’)
- get_property_default(name: str) str | None[source]¶
Source text of the Property’s default expression, or
None.Inherited Properties are not visible — use the runtime tree to observe inherited values.
- add_property(name: str, default_expr: str) None[source]¶
Insert
name = Property(default_expr)into the class body.Inserted after existing class-level Property declarations. Auto- imports
Propertyvia the file’s :class:ImportSet.
- set_root_kwarg(name: str, value_expr: str) None[source]¶
Update or insert a kwarg in the root
super().__init__(...)call.
- child_var_names() list[str][source]¶
Variable names of all children added via
self.add_child(<var>), in source order.
- add_child(var_name: str, type_name: str, *, before: str | None = None, after: str | None = None, from_module: str = 'simvx.core', **kwarg_exprs: str) None[source]¶
Insert a child construction +
self.add_childpair into__init__.Position: appended at the end of the existing child block by default;
before=orafter=(mutually exclusive) places relative to another child.Auto-imports
type_namefromfrom_module(defaults tosimvx.core) when the name is not already imported under any alias. Callers placing user classes should passfrom_module=type(node).__module__.Raises :class:
ValueErrorifvar_namealready exists in the__init__body or if bothbeforeandafterare passed.Note: when the source is procedural (children built inside loops or conditionals — see :func:
has_procedural_construction), the inserted statements are appended at the top level of__init__and may execute in a surprising order relative to the procedural code.
- class simvx.core.scene_io.scene_file.ImportSet(source_tree: simvx.core.scene_io.source_tree.SourceTree)[source]¶
Editable view of the file’s top-level imports.
Initialization
- __slots__¶
(‘_source_tree’,)
- ensure(name: str, *, from_: str | None = None) None[source]¶
Add
import nameorfrom <from_> import nameif absent.When
from_matches an existingfrom <from_> import …line, the new name is merged into that line (sorted, deduplicated) instead of creating a separate import line.