lvkit 0.8.2__tar.gz → 0.8.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lvkit-0.8.2 → lvkit-0.8.4}/PKG-INFO +1 -1
- {lvkit-0.8.2 → lvkit-0.8.4}/pyproject.toml +1 -1
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/__init__.py +1 -1
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/cache_paths.py +49 -10
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/extractor.py +29 -15
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/builders/operations.py +6 -2
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/loading.py +173 -21
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/models.py +9 -8
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/parallel_parse.py +15 -6
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/output_cache.py +38 -15
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/metadata.py +26 -9
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/node_types.py +30 -24
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/vi.py +65 -22
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/base.py +88 -7
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/invoke_node.py +20 -19
- lvkit-0.8.4/src/lvkit/render/glyphs/nodes/property_node.py +78 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/nodes.py +111 -32
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/scene.py +15 -6
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/style.py +26 -2
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/theme_web.py +1 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/structure.py +61 -9
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/conftest.py +24 -0
- lvkit-0.8.4/tests/test_cache_path_bound.py +331 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_class_parent_linkinfo.py +22 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_class_wire_appearance.py +54 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_constant_decoding.py +45 -0
- lvkit-0.8.4/tests/test_decode_element_perf.py +107 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_extraction_cache.py +28 -9
- lvkit-0.8.4/tests/test_lvlib_nonvi_member.py +53 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_output_cache.py +10 -6
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_parser.py +144 -0
- lvkit-0.8.4/tests/test_python_structure_plan.py +55 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_render.py +316 -12
- lvkit-0.8.2/src/lvkit/render/glyphs/nodes/property_node.py +0 -115
- {lvkit-0.8.2 → lvkit-0.8.4}/.gitignore +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/.pre-commit-config.yaml +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/LICENSE +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/NOTICE +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/README.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/deploy/cloudrun/README.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/docs/_internal/xml-schema/README.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/editors/vscode/LICENSE +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/editors/vscode/README.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/mcpb/README.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/plugin/README.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/audit_primitive_consistency.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/audit_terminal_order.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/audit_unresolved.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/build_example_pages.sh +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/build_hero.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/build_ni_function_catalog.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/connector_geometry_audit.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/dump_primitive_context.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/extract_corpus.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/gen_semantics_probe.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/generate_docs.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/generate_driver_data.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/generate_python.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/import_nodes_primitives.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/list_unknown_primitives.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/populate_vilib.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/pull_samples.sh +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/recategorize_vilib.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/render_gallery.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/reproduce_openg_corpus.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/study_unwired_direction.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/scripts/wire_decode_probe.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/__main__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/_data.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/_pylabview_patches.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/cli.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/README.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/ast_optimizer.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/ast_utils.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/builder.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/class_builder/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/class_builder/_shared.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/class_builder/config.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/class_builder/core.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/class_builder/init_builder.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/class_builder/methods.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/class_builder/naming.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/class_builder/properties.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/class_builder/terminals.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/condition_builder.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/context.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/dataflow.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/elementwise.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/error_handler.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/expressions.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/fragment.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/function.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/imports.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/base.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/case.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/compound.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/constant.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/event.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/first_call.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/formula.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/in_place.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/invoke_node.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/loop.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/nmux.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/primitive.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/printf.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/property_node.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/queue_ops.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/sequence.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/nodes/subvi.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/stubs.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/codegen/unresolved.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/connector_geometry.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/connector_pane_geometry.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/builtin_types.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/connector_pane_patterns.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/drivers/_index.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/drivers/daqmx.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/drivers/nidcpower.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/drivers/nidigital.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/drivers/nidmm.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/drivers/nifgen.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/drivers/niscope.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/drivers/niswitch.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/drivers/serial.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/drivers/visa.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/labview_error_codes.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/measure_data.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/openg/_index.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/openg/array.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/openg/file.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/openg/string.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/openg/time.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/openg/variant.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/primitives.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/_index.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/_pending_terminals.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/_types.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/addons.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/application-control.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/array.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/boolean.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/cluster-class-variant.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/collection.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/comparison.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/connectivity.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/control-simulation.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/data-communication.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/dialog-user-interface.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/express.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/file-io.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/graphics-sound.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/instrument-io.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/mathematics.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/measurement-io.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/numeric.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/report-generation.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/signal-processing.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/string.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/structures.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/synchronization.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/timing.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/data/vilib/waveform.json +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/generate.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/html_generator/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/html_generator/assets.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/html_generator/class_page.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/html_generator/core.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/html_generator/index_page.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/html_generator/naming.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/html_generator/vi_page.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/template.css +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/docs/utils.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/flattened_typedesc.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/formula/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/formula/cparser.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/formula/emit.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/formula/lexer.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/formula/nodes.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/analysis.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/builders/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/builders/context.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/builders/refs.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/builders/structures.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/construction.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/core.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/describe.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/diff.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/interface_order.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/lvnet_grammar.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/lvnet_parse.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/lvnet_reconstruct.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/netlist.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/netlist_build.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/netlist_diff_helpers.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/netlist_json.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/netlist_models.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/op_walk.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/operations.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/queries.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/graph/render_lvnet.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/index/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/index/build.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/index/model.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/index/project.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/index/query.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/index/sql.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/index/store.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/labview_error.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/labview_error_codes.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/labview_queue.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/load_mode.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/lv_detect.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/mcp/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/mcp/schemas.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/mcp/server/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/mcp/server/__main__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/mcp/server/_compat.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/mcp/server/app.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/mcp/server/index_tools.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/mcp/server/resolvers.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/mcp/server/roots.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/mcp/server/vi_tools.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/measure_data.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/models.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/num_format.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/conp_types.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/constants.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/defaults.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/flags.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/fp_heap_type.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/front_panel.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/image_resources.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/layout.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/models.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/naming.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/nodes/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/nodes/base.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/nodes/case.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/nodes/constant.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/nodes/decompose.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/nodes/disable.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/nodes/event.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/nodes/free_label.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/nodes/loop.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/nodes/sequence.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/type_mapping.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/type_resolution.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/utils.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/parser/wire_table.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/pipeline.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/primitive_resolver/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/primitive_resolver/exceptions.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/primitive_resolver/models.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/primitive_resolver/resolver.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/project_store.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/py.typed +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/ARCHITECTURE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/backend.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/composite.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/connector_pane.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/connector_pane_panel.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/diff_viewer.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/draw.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyph.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/decorations/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/decorations/arrow.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/decorations/base.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/decorations/factory.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/decorations/fallback.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/decorations/frame.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/decorations/line.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/decorations/picture.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/arith.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/array_build.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/array_constant.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/array_reverse.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/array_search.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/array_size.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/array_sort.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/array_split.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/boolean_constant.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/boolean_gate.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/bundle.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/bundle_by_name.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/centered_svg.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/class_glyph.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/cluster_constant.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/compound_arith.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/constant.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/control_ref_const.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/convert.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/error_cluster.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/event_data.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/event_reg_node.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/formula_node.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/icon_image.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/in_place_element.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/inline_svg.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/label.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/local_variable.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/path_glyph.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/refnum_glyph.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/unbundle.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/variant.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/nodes/wrapped_box.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/base.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/case.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/disable.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/event.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/factory.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/flat_sequence.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/for_loop.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/generic.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/in_place.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/selectable.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/stacked_sequence.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/structures/while_loop.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/autoindex.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/base.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/concatenate.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/conditional.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/event_dyn.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/event_timeout.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/factory.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/generic.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/loop_count.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/selector.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/shift_register.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/glyphs/terminals/tunnel.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/help_tip.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/icons.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/lane_pass.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/properties_panel.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/render_viewer.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/templates/diff_viewer.html +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/templates/render_viewer.html +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/theme_control.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/render/wire_router.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/runtime/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/runtime/lv.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/skill_templates/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/skill_templates/lvkit/SKILL.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/skill_templates/lvkit-convert/SKILL.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/skill_templates/lvkit-describe/SKILL.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/skill_templates/lvkit-document/SKILL.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/skill_templates/lvkit-query/SKILL.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/skill_templates/lvkit-resolve/SKILL.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/skill_templates/lvkit-review/SKILL.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/terminal_collector.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/text_encoding.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/tools/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/tools/connector_geometry_profile.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/type_defaults.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/unresolved.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/vi_diff.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/vilib_resolver/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/vilib_resolver/exceptions.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/vilib_resolver/loader.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/vilib_resolver/lookup.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/vilib_resolver/models.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/vilib_resolver/naming.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/vilib_resolver/resolver.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/src/lvkit/vilib_resolver/variants.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/__init__.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/Test LVKit/Lib1/Class/Class.lvclass +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/Test LVKit/Lib1/Class/Do.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/Test LVKit/Lib1/Lib1.lvlib +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/Test LVKit/Lib2/Class/Class.lvclass +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/Test LVKit/Lib2/Class/Do.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/Test LVKit/Lib2/Class/Test.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/Test LVKit/Lib2/Lib2.lvlib +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/Test LVKit/Test LVKit.aliases +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/Test LVKit/Test LVKit.lvlps +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/29/Test LVKit/Test LVKit.lvproj +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/30/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/30/visible-frame-case-sequence.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/30/visible-frame-conditional-disable.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/31/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/31/disable-structure-frame-names.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/32/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/32/comments-and-decorations.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/33/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/33/coercion-dot-consistency.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/34/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/34/hidden-iteration-terminal.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/35/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/35/objects-hidden-by-structures.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/36/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/36/bundle-unbundle-names.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/37/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/37/structure-tunnel-wire-bends.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/38/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/38/auto-concatenating-tunnel.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/39/PROVENANCE.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/39/zorder-not-respected.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/82/Pictures And Decorations.vi +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/corpus/issues/README.md +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/helpers.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_array_ops_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_ast_builder.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_ast_optimizer.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_case_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_case_parser.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_class_field_walkup.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_class_properties.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_cli.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_cli_cache.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_cli_describe_lvnet.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_cli_graph_ops.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_cli_query.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_cluster_wire_color.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_codegen_context.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_compound_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_condition_builder.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_connector_geometry.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_connector_pane_label_recovery.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_connector_pane_patterns.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_connector_pane_render.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_conp_types.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_dependency_path_refs.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_determinism.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_diff.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_diff_properties.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_diff_viewer.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_disable_graph.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_disable_parser.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_docs_class_hierarchy.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_docs_render.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_driver_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_dynamic_dispatch.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_e2e_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_elementwise.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_error_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_error_handling.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_error_terminal_label_fallback.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_event_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_event_parser.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_extractor_concurrency.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_extractor_long_path.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_first_call_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_formula_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_formula_runtime.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_formula_semantics.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_formula_transpile.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_fp_heap_type.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_frame_attribution.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_frame_zplane.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_glyphs.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_graceful_degradation.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_help_tip.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_import_startup.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_in_place_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_index.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_index_sql.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_index_warm_no_downgrade.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_interface_order.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_issue_corpus.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_label_extraction.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_labview_queue.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_livi_vipi.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_load_mode.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_load_upgrade.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_loop_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_lv_detect.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_lvnet_identity.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_lvnet_reconstruct.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_lvnet_roundtrip.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_lvpy.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_mcp_cache.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_mcp_evals.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_mcp_read_vi_lvnet.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_mcp_roots.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_naming.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_netlist_json.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_new_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_node_properties.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_parallel_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_parallel_parse.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_parser_regression.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_primitive_name_uniqueness.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_primitive_positional_order.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_primitive_resolutions.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_progressive_index.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_progressive_warm.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_project_store.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_queue_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_render_emission_order.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_render_lvnet.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_render_title_identity.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_render_viewer.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_sequence.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_soft_codegen.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_structure_lvproj.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_subvi_nav.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_text_encoding.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_type_driven_fixes.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_type_fields.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_type_loading.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_type_mapping.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_unknown_nodes.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_unresolved.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_vi_graph.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_vi_properties.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_viewer_properties.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_vilib_docurls.py +0 -0
- {lvkit-0.8.2 → lvkit-0.8.4}/tests/test_web_progressive_staging.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: lvkit
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.4
|
|
4
4
|
Summary: Understand and convert LabVIEW VIs to Python without a LabVIEW license
|
|
5
5
|
Project-URL: Repository, https://github.com/pragmatest-dev/lvkit
|
|
6
6
|
Project-URL: Issues, https://github.com/pragmatest-dev/lvkit/issues
|
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
__version__ = "0.8.
|
|
7
|
+
__version__ = "0.8.4"
|
|
8
8
|
|
|
9
9
|
# The public API is exposed LAZILY (PEP 562 module ``__getattr__``): the graph /
|
|
10
10
|
# parser / structure stacks (networkx, pydantic, pylabview, PIL — ~230 ms) load
|
|
@@ -111,6 +111,35 @@ def _slug(path: Path) -> str:
|
|
|
111
111
|
return f"{tail}-{h}"
|
|
112
112
|
|
|
113
113
|
|
|
114
|
+
# The fixed short stem every MANAGED-cache artifact (extract/render/diff) uses
|
|
115
|
+
# instead of the real VI's filename stem — the second Windows MAX_PATH axis
|
|
116
|
+
# alongside the bounded ``vi-<hash>`` slot below. Owned by this module (the
|
|
117
|
+
# single source of the cache-layout policy); ``extractor.py`` and
|
|
118
|
+
# ``output_cache.py`` import it rather than repeating the literal.
|
|
119
|
+
MANAGED_ARTIFACT_STEM = "vi"
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _vi_slot(rel: Path) -> str:
|
|
123
|
+
"""A per-VI cache dir name that is ALWAYS bounded, whatever the source tree's
|
|
124
|
+
depth: ``vi-`` + 16 hex of a sha256 of the owner-relative path.
|
|
125
|
+
|
|
126
|
+
Owned namespaces used to hang a VI's cache under ``<rel.parent>`` — the full
|
|
127
|
+
source-directory hierarchy reproduced beneath the cache root. A deep repo (or
|
|
128
|
+
a long VI filename) then pushed the final cache path past Windows' MAX_PATH
|
|
129
|
+
even with a short ``LVKIT_CACHE_DIR``, because BOTH the depth and the source
|
|
130
|
+
stem were unbounded inputs (the failure this replaces). Collapsing the whole
|
|
131
|
+
owner-relative path to one fixed-width hash segment removes the depth axis;
|
|
132
|
+
fixed short artifact names inside the slot remove the stem axis. The path is
|
|
133
|
+
keyed on the FULL ``rel`` (parent + filename), so every source VI maps to its
|
|
134
|
+
own slot and sibling VIs never collide. The real source path is NOT lost — it
|
|
135
|
+
is recorded as the ``source`` field of each slot's ``.meta.json`` sidecar
|
|
136
|
+
(see ``extractor._write_cache_meta`` / ``output_cache._write``). The
|
|
137
|
+
separators are normalized to ``/`` so the same VI hashes identically
|
|
138
|
+
regardless of how its path was spelled on this platform."""
|
|
139
|
+
key = rel.as_posix()
|
|
140
|
+
return "vi-" + hashlib.sha256(key.encode("utf-8")).hexdigest()[:16]
|
|
141
|
+
|
|
142
|
+
|
|
114
143
|
def kind_fingerprint(kind: str) -> str:
|
|
115
144
|
"""The 8-hex build-compatibility tag stamped into a cache path for ``kind``.
|
|
116
145
|
|
|
@@ -215,14 +244,20 @@ def classify(vi_path: Path, kind: str) -> tuple[Path, str, str]:
|
|
|
215
244
|
"""Map ``vi_path`` to ``(cache_dir, source_label, namespace)`` for one
|
|
216
245
|
artifact ``kind`` (``"extract"`` | ``"render"`` | ``"diff"``).
|
|
217
246
|
|
|
218
|
-
``cache_dir`` is ``<cache>/<ns>/<slug>/<kind>/<fp
|
|
247
|
+
``cache_dir`` is ``<cache>/<ns>/<slug>/<kind>/<fp>/vi-<hash>`` — project-
|
|
219
248
|
first: the VI's identity (namespace + slug) is named ONCE and the ``kind``
|
|
220
|
-
hangs off it, so one project's whole cache is a single subtree
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
249
|
+
hangs off it, so one project's whole cache is a single subtree. ``<fp>`` is
|
|
250
|
+
the per-kind build tag (:func:`kind_fingerprint`) so two incompatible lvkit
|
|
251
|
+
builds get separate slots instead of clobbering each other. ``vi-<hash>``
|
|
252
|
+
(:func:`_vi_slot`) is a bounded per-VI slot standing in for the owner-relative
|
|
253
|
+
directory hierarchy, so an arbitrarily deep source tree can never push the
|
|
254
|
+
cache path past Windows' MAX_PATH; the artifact names inside it are fixed and
|
|
255
|
+
short (``vi_BDHb.xml`` / ``vi.<ext>``) for the same reason. ``source_label``
|
|
256
|
+
stays the REAL owner-relative path (``str(rel)``) so the true source is
|
|
257
|
+
recorded in each slot's ``.meta.json``. ``namespace`` is ``"projects"``,
|
|
224
258
|
``"shared"``, or ``"adhoc"`` — callers path-address the first two and
|
|
225
|
-
content-address ``adhoc`` (its paths never repeat
|
|
259
|
+
content-address ``adhoc`` (its paths never repeat; its dir is already a single
|
|
260
|
+
bounded ``_slug`` segment).
|
|
226
261
|
"""
|
|
227
262
|
resolved = vi_path.resolve()
|
|
228
263
|
cache = global_cache_root()
|
|
@@ -237,7 +272,7 @@ def classify(vi_path: Path, kind: str) -> tuple[Path, str, str]:
|
|
|
237
272
|
rel = _rel_under(resolved, vilib)
|
|
238
273
|
if rel is not None:
|
|
239
274
|
_note_owner(vilib)
|
|
240
|
-
d = cache / "shared" / "vilib" / _slug(vilib) / kind / fp / rel
|
|
275
|
+
d = cache / "shared" / "vilib" / _slug(vilib) / kind / fp / _vi_slot(rel)
|
|
241
276
|
return d, str(rel), "shared"
|
|
242
277
|
|
|
243
278
|
userlib = _userlib_root
|
|
@@ -245,7 +280,8 @@ def classify(vi_path: Path, kind: str) -> tuple[Path, str, str]:
|
|
|
245
280
|
rel = _rel_under(resolved, userlib)
|
|
246
281
|
if rel is not None:
|
|
247
282
|
_note_owner(userlib)
|
|
248
|
-
|
|
283
|
+
slug = _slug(userlib)
|
|
284
|
+
d = cache / "shared" / "userlib" / slug / kind / fp / _vi_slot(rel)
|
|
249
285
|
return d, str(rel), "shared"
|
|
250
286
|
|
|
251
287
|
project = _project_root_for(resolved)
|
|
@@ -253,7 +289,7 @@ def classify(vi_path: Path, kind: str) -> tuple[Path, str, str]:
|
|
|
253
289
|
proj_abs = project.resolve()
|
|
254
290
|
rel = resolved.relative_to(proj_abs)
|
|
255
291
|
_note_owner(proj_abs)
|
|
256
|
-
d = cache / "projects" / _slug(proj_abs) / kind / fp / rel
|
|
292
|
+
d = cache / "projects" / _slug(proj_abs) / kind / fp / _vi_slot(rel)
|
|
257
293
|
return d, str(rel), "projects"
|
|
258
294
|
|
|
259
295
|
# adhoc has NO owner (not a project, not a library) -> no identity slug to
|
|
@@ -474,7 +510,10 @@ def write_meta(vi_path: Path, meta_path: Path, **extra: object) -> None:
|
|
|
474
510
|
# source/fingerprint change — that is handled by the <fp> path level). A mismatch
|
|
475
511
|
# triggers a one-time drop of the derived namespaces in cleanup_legacy_cache.
|
|
476
512
|
# "2": project-first with a per-kind <fp> level and <tail>-<hash8> slugs.
|
|
477
|
-
|
|
513
|
+
# "3": owned VIs sit in a bounded per-VI ``vi-<hash>`` slot with fixed short
|
|
514
|
+
# artifact names (was the reproduced ``<rel.parent>`` hierarchy + source
|
|
515
|
+
# stem), so a deep source tree can't overflow Windows MAX_PATH.
|
|
516
|
+
_LAYOUT_VERSION = "3"
|
|
478
517
|
|
|
479
518
|
|
|
480
519
|
def cleanup_legacy_cache() -> None:
|
|
@@ -34,6 +34,7 @@ install_pylabview_patches()
|
|
|
34
34
|
# pylabview). Re-exported here so long-standing callers of ``extractor.X`` (e.g.
|
|
35
35
|
# ``graph.core`` -> ``extractor.set_extraction_roots``) keep working unchanged.
|
|
36
36
|
from lvkit.cache_paths import ( # noqa: E402
|
|
37
|
+
MANAGED_ARTIFACT_STEM,
|
|
37
38
|
_slug,
|
|
38
39
|
classify,
|
|
39
40
|
cleanup_legacy_cache,
|
|
@@ -179,7 +180,7 @@ def _make_read_po(**overrides: object) -> argparse.Namespace:
|
|
|
179
180
|
return argparse.Namespace(**opts)
|
|
180
181
|
|
|
181
182
|
|
|
182
|
-
def _extract_in_process(vi_path: Path, output_dir: Path,
|
|
183
|
+
def _extract_in_process(vi_path: Path, output_dir: Path, artifact_stem: str) -> None:
|
|
183
184
|
"""Extract a VI to XML in-process, matching ``readRSRC -i <vi> -x``.
|
|
184
185
|
|
|
185
186
|
pylabview places each block's sidecar XML (``_BDHb.xml`` etc.) in
|
|
@@ -190,17 +191,21 @@ def _extract_in_process(vi_path: Path, output_dir: Path, vi_stem: str) -> None:
|
|
|
190
191
|
request concurrency. This avoids the per-call interpreter boot + pylabview
|
|
191
192
|
re-import that the subprocess path pays on every extraction.
|
|
192
193
|
|
|
194
|
+
``artifact_stem`` names the produced files — the caller's real VI stem for a
|
|
195
|
+
caller-owned ``output_dir``, or the fixed ``MANAGED_ARTIFACT_STEM`` in the
|
|
196
|
+
managed cache; it is NOT necessarily ``vi_path.stem``.
|
|
197
|
+
|
|
193
198
|
Mirrors the option set that ``readRSRC.main()`` builds for the ``-x``
|
|
194
199
|
(extract) subcommand via argparse.
|
|
195
200
|
"""
|
|
196
|
-
xml_path = output_dir / f"{
|
|
201
|
+
xml_path = output_dir / f"{artifact_stem}.xml"
|
|
197
202
|
po = _make_read_po(
|
|
198
203
|
rsrc=str(vi_path),
|
|
199
204
|
xml=str(xml_path),
|
|
200
205
|
textcp="mac_roman",
|
|
201
206
|
raw_connectors=False,
|
|
202
207
|
keep_names=False,
|
|
203
|
-
filebase=
|
|
208
|
+
filebase=artifact_stem,
|
|
204
209
|
list=False,
|
|
205
210
|
dump=False,
|
|
206
211
|
extract=True,
|
|
@@ -214,8 +219,8 @@ def _extract_in_process(vi_path: Path, output_dir: Path, vi_stem: str) -> None:
|
|
|
214
219
|
with open(xml_path, "wb") as xml_fh:
|
|
215
220
|
tree.write(xml_fh, encoding="utf-8", xml_declaration=True)
|
|
216
221
|
for path in output_dir.iterdir():
|
|
217
|
-
belongs_to_vi = path.name == f"{
|
|
218
|
-
f"{
|
|
222
|
+
belongs_to_vi = path.name == f"{artifact_stem}.xml" or path.name.startswith(
|
|
223
|
+
f"{artifact_stem}_"
|
|
219
224
|
)
|
|
220
225
|
if path.suffix == ".xml" and belongs_to_vi:
|
|
221
226
|
normalize_extracted_xml(path)
|
|
@@ -249,15 +254,24 @@ def extract_vi_xml(
|
|
|
249
254
|
"""
|
|
250
255
|
vi_path = Path(vi_path).resolve()
|
|
251
256
|
|
|
252
|
-
|
|
257
|
+
# A caller-supplied output_dir is caller-owned, so keep the real source stem
|
|
258
|
+
# in the artifact names there. The MANAGED cache (output_dir is None) uses a
|
|
259
|
+
# FIXED short stem instead: a long source filename would otherwise overflow
|
|
260
|
+
# the cache path once a ``_BDHb.xml`` suffix is appended — the second Windows
|
|
261
|
+
# MAX_PATH axis, paired with the bounded per-VI slot dir (cache_paths._vi_slot).
|
|
262
|
+
# The real source name/path is preserved for callers: the graph loader keys
|
|
263
|
+
# every node on the source path (never on this stem), and the ``source`` field
|
|
264
|
+
# of the ``.meta.json`` records the real owner-relative path.
|
|
265
|
+
managed = output_dir is None
|
|
266
|
+
if managed:
|
|
253
267
|
output_dir = _cache_target(vi_path)
|
|
254
268
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
255
269
|
|
|
256
|
-
|
|
257
|
-
bd_xml = output_dir / f"{
|
|
258
|
-
fp_xml = output_dir / f"{
|
|
259
|
-
main_xml = output_dir / f"{
|
|
260
|
-
meta_path = output_dir / f"{
|
|
270
|
+
artifact_stem = MANAGED_ARTIFACT_STEM if managed else vi_path.stem
|
|
271
|
+
bd_xml = output_dir / f"{artifact_stem}_BDHb.xml"
|
|
272
|
+
fp_xml = output_dir / f"{artifact_stem}_FPHb.xml"
|
|
273
|
+
main_xml = output_dir / f"{artifact_stem}.xml"
|
|
274
|
+
meta_path = output_dir / f"{artifact_stem}.meta.json"
|
|
261
275
|
|
|
262
276
|
# Cache hit: XML present and the recorded content-hash (or mtime/size
|
|
263
277
|
# fast-path) still matches the VI. The extraction-code compatibility check is
|
|
@@ -316,15 +330,15 @@ def extract_vi_xml(
|
|
|
316
330
|
tmp_dir = Path(tempfile.mkdtemp(prefix=".x-", dir=_staging_root()))
|
|
317
331
|
try:
|
|
318
332
|
try:
|
|
319
|
-
_extract_in_process(vi_path, tmp_dir,
|
|
333
|
+
_extract_in_process(vi_path, tmp_dir, artifact_stem)
|
|
320
334
|
except Exception as exc:
|
|
321
335
|
raise RuntimeError(
|
|
322
336
|
f"pylabview extraction failed for {vi_path.name}: {exc}"
|
|
323
|
-
f"{_windows_long_path_hint(tmp_dir / f'{
|
|
337
|
+
f"{_windows_long_path_hint(tmp_dir / f'{artifact_stem}_BDHb.xml')}"
|
|
324
338
|
) from exc
|
|
325
339
|
|
|
326
|
-
if not (tmp_dir / f"{
|
|
327
|
-
raise RuntimeError(f"Block diagram XML not found: {
|
|
340
|
+
if not (tmp_dir / f"{artifact_stem}_BDHb.xml").exists():
|
|
341
|
+
raise RuntimeError(f"Block diagram XML not found: {artifact_stem}_BDHb.xml")
|
|
328
342
|
|
|
329
343
|
# Publish every produced artifact atomically (same filesystem as the
|
|
330
344
|
# temp dir), then meta.json last so its appearance marks the cache valid.
|
|
@@ -99,6 +99,12 @@ class PrimitiveBuildHandler(NodeBuildHandler):
|
|
|
99
99
|
if isinstance(node, (PropertyNode, InvokeNode, EventRegNode)):
|
|
100
100
|
prim_kwargs["object_name"] = node.object_name
|
|
101
101
|
prim_kwargs["object_method_id"] = node.object_method_id
|
|
102
|
+
# Property/Invoke nodes share the SAME implicit-binding fields
|
|
103
|
+
# (task #51/#55) -- EventRegNode has neither, so it's excluded
|
|
104
|
+
# here rather than duplicating this pair per elif branch below.
|
|
105
|
+
if isinstance(node, (PropertyNode, InvokeNode)):
|
|
106
|
+
prim_kwargs["bound_control_uid"] = node.bound_control_uid
|
|
107
|
+
prim_kwargs["bound_control_type"] = node.bound_control_type
|
|
102
108
|
if isinstance(node, PropertyNode):
|
|
103
109
|
prim_kwargs["properties"] = [
|
|
104
110
|
PropertyDef(name=p.get("name", "")) if isinstance(p, dict) else p
|
|
@@ -107,8 +113,6 @@ class PrimitiveBuildHandler(NodeBuildHandler):
|
|
|
107
113
|
prim_kwargs["property_value_terminal_ids"] = [
|
|
108
114
|
ctx.qid(uid) for uid in node.dco_terminal_uids
|
|
109
115
|
]
|
|
110
|
-
prim_kwargs["bound_control_uid"] = node.bound_control_uid
|
|
111
|
-
prim_kwargs["bound_control_type"] = node.bound_control_type
|
|
112
116
|
elif isinstance(node, InvokeNode):
|
|
113
117
|
prim_kwargs["method_name"] = node.method_name
|
|
114
118
|
prim_kwargs["method_code"] = node.method_code
|
|
@@ -496,8 +496,10 @@ class LoadingMixin:
|
|
|
496
496
|
|
|
497
497
|
for member in lib.members:
|
|
498
498
|
if member.member_type == "VI":
|
|
499
|
-
|
|
500
|
-
|
|
499
|
+
member_url = Path(member.url)
|
|
500
|
+
member_name = member_url.name
|
|
501
|
+
member_suffix = member_url.suffix.lower()
|
|
502
|
+
if member_suffix == ".ctl":
|
|
501
503
|
# .ctl members are type definitions, not loadable VIs
|
|
502
504
|
typedef_qname = lib_qname + ":" + member_name
|
|
503
505
|
ctl_path = lvlib_path.parent / member.url
|
|
@@ -528,7 +530,7 @@ class LoadingMixin:
|
|
|
528
530
|
caller=lib_key,
|
|
529
531
|
rel="owns",
|
|
530
532
|
)
|
|
531
|
-
|
|
533
|
+
elif member_suffix == ".vi":
|
|
532
534
|
member_qname = lib_qname + ":" + member_name
|
|
533
535
|
vi_path = lvlib_path.parent / member.url
|
|
534
536
|
if not vi_path.exists():
|
|
@@ -558,6 +560,21 @@ class LoadingMixin:
|
|
|
558
560
|
caller=lib_key,
|
|
559
561
|
rel="owns",
|
|
560
562
|
)
|
|
563
|
+
else:
|
|
564
|
+
# A member the library XML declares Type="VI" but whose URL
|
|
565
|
+
# is neither .vi nor .ctl -- a source-metadata anomaly, not
|
|
566
|
+
# a code entity. No node, no stub (a stub means "a VI we
|
|
567
|
+
# expect to resolve later", which is wrong here): warn and
|
|
568
|
+
# move on rather than sending a non-VI file to load_vi
|
|
569
|
+
# (which raises ValueError and would abort the whole load).
|
|
570
|
+
logger.warning(
|
|
571
|
+
'library %s declares member %r as Type="VI" but its '
|
|
572
|
+
"URL %r is not a loadable .vi or .ctl file — skipping "
|
|
573
|
+
"it.",
|
|
574
|
+
lvlib_path.name,
|
|
575
|
+
member.name,
|
|
576
|
+
member.url,
|
|
577
|
+
)
|
|
561
578
|
elif member.member_type == "LVClass":
|
|
562
579
|
class_name = Path(member.url).name
|
|
563
580
|
class_path = lvlib_path.parent / member.url
|
|
@@ -647,13 +664,14 @@ class LoadingMixin:
|
|
|
647
664
|
search_paths: list[Path] | None = None,
|
|
648
665
|
owner_chain: list[str] | None = None,
|
|
649
666
|
) -> str:
|
|
650
|
-
"""Load a .lvclass file. Returns the
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
667
|
+
"""Load a .lvclass file. Returns the dep-graph KEY (the resolved
|
|
668
|
+
``.lvclass`` path) it was registered under — mirrors ``load_lvlib``/
|
|
669
|
+
``load_typedef``: callers add ownership/reference edges to THIS key,
|
|
670
|
+
never to the qname (``cls_qname``, built from the ON-DISK file's own
|
|
671
|
+
stem casing — the CALLER may have referenced this class under a
|
|
672
|
+
different casing, e.g. a type reference's recorded casing can differ
|
|
673
|
+
from the file's actual casing, so the qname alone isn't a safe edge
|
|
674
|
+
target; see ``_load_dependency``'s ``.lvclass`` branch).
|
|
657
675
|
|
|
658
676
|
``MINIMAL`` is an INTERFACE load: add the class's private-data fields
|
|
659
677
|
(and its parent chain's, via walk-up — nMux field indices run into the
|
|
@@ -686,7 +704,9 @@ class LoadingMixin:
|
|
|
686
704
|
# walks follow it by IDENTITY (a name can hit duplicates; a path
|
|
687
705
|
# can't). None when the parent isn't on disk.
|
|
688
706
|
parent = cls.parent_class
|
|
689
|
-
parent_file, parent_intended = self._resolve_parent(
|
|
707
|
+
parent_file, parent_intended = self._resolve_parent(
|
|
708
|
+
cls, lvclass_path, search_paths
|
|
709
|
+
)
|
|
690
710
|
# The parent's KEY is its recorded path whether or not the file is staged
|
|
691
711
|
# yet — so progressive (web) staging can NAME + fetch a not-yet-present
|
|
692
712
|
# parent (an ``.exists()`` gate would drop the whole inherited surface).
|
|
@@ -832,6 +852,18 @@ class LoadingMixin:
|
|
|
832
852
|
try:
|
|
833
853
|
pd_fields = private_data_from_lvclass_xml(lvclass_path)
|
|
834
854
|
except Exception:
|
|
855
|
+
# Intentional hard best-effort boundary, not a narrowable
|
|
856
|
+
# set: private_data_from_lvclass_xml decodes a possibly
|
|
857
|
+
# malformed/legacy embedded RSRC container through
|
|
858
|
+
# pylabview's OWN VI-resource parser (parse_flattened_
|
|
859
|
+
# private_data -> lv_rsrc.VI(...).parseData()), whose
|
|
860
|
+
# exception surface on untrusted/old-format binary data
|
|
861
|
+
# isn't a documented closed set (struct/index/value/key
|
|
862
|
+
# errors and more have all been observed from that parser
|
|
863
|
+
# elsewhere) -- this docstring's own contract is "a
|
|
864
|
+
# malformed/older embedded control must never break class
|
|
865
|
+
# loading", so any failure here degrades to "no fields
|
|
866
|
+
# recovered", never propagates.
|
|
835
867
|
logger.debug(
|
|
836
868
|
"flattened private-data recovery failed for %s",
|
|
837
869
|
lvclass_path,
|
|
@@ -841,23 +873,119 @@ class LoadingMixin:
|
|
|
841
873
|
fields = [private_data_field_to_cluster_field(f) for f in pd_fields]
|
|
842
874
|
return fields
|
|
843
875
|
|
|
876
|
+
def _resolve_vilib_class_ref(
|
|
877
|
+
self,
|
|
878
|
+
parent_name: str,
|
|
879
|
+
path_tokens: list[str],
|
|
880
|
+
lvclass_path: Path,
|
|
881
|
+
search_paths: list[Path],
|
|
882
|
+
) -> tuple[Path | None, Path | None]:
|
|
883
|
+
"""Resolve a ``<vilib>``-rooted class reference's TOKENS (already
|
|
884
|
+
split — ``path_tokens[0] == "<vilib>"``) -> ``(parent_file,
|
|
885
|
+
parent_intended)``, via ``ParsedDependencyRef.resolve_against`` — the
|
|
886
|
+
EXACT SAME machinery a SubVI/type ``<vilib>`` dependency already
|
|
887
|
+
resolves through (``_resolve_dependency_path``), never a new
|
|
888
|
+
resolver. Shared by BOTH ``<vilib>``-rooted sources ``_resolve_parent``
|
|
889
|
+
can see (a plain-XML ``Parent`` Item's URL, and the binary
|
|
890
|
+
``ParentClassLinkInfo``'s own recorded path — issue #84's #F1
|
|
891
|
+
correction: the URL case was previously naively joined, leaving a
|
|
892
|
+
literal ``<vilib>`` path component that never exists).
|
|
893
|
+
|
|
894
|
+
A configured ``vilib_root`` gives an exact, scan-free hit; otherwise
|
|
895
|
+
``<vilib>`` maps onto ``search_paths`` (this loader's already-
|
|
896
|
+
configured SubVI roots) the same way, with ``_find_file``'s existing
|
|
897
|
+
bounded per-search-path lookup (used for every other unresolved
|
|
898
|
+
dependency) actually LOCATING the file when it's nested deeper than
|
|
899
|
+
a direct join reaches (e.g. actor-framework vendors ``Actor.lvclass``
|
|
900
|
+
under an extra ``Core/`` level the recorded path itself doesn't
|
|
901
|
+
record — LabVIEW's own vi.lib layout has no such prefix).
|
|
902
|
+
``parent_intended`` is still produced via pure path math even when
|
|
903
|
+
no local file is found (one of ``vilib_root``/``search_paths[0]``),
|
|
904
|
+
so progressive/web staging can NAME + fetch it — never
|
|
905
|
+
``.exists()``-gated away, same contract as the method-path code in
|
|
906
|
+
``load_lvclass`` above."""
|
|
907
|
+
parent_file: Path | None = None
|
|
908
|
+
parent_intended: Path | None = None
|
|
909
|
+
dep_ref = ParsedDependencyRef(
|
|
910
|
+
name=parent_name + ".lvclass", path_tokens=path_tokens
|
|
911
|
+
)
|
|
912
|
+
candidate = dep_ref.resolve_against(
|
|
913
|
+
lvclass_path,
|
|
914
|
+
vilib_root=self._vilib_root,
|
|
915
|
+
userlib_root=self._userlib_root,
|
|
916
|
+
instrlib_root=self._instrlib_root,
|
|
917
|
+
)
|
|
918
|
+
if candidate is not None:
|
|
919
|
+
parent_intended = candidate
|
|
920
|
+
if candidate.exists():
|
|
921
|
+
parent_file = candidate
|
|
922
|
+
# Both the search_paths glob AND the search_paths[0]-as-vilib_root
|
|
923
|
+
# intended-path fallback are skipped once EITHER parent_file OR
|
|
924
|
+
# parent_intended is already known -- no point globbing when the
|
|
925
|
+
# exact vilib_root candidate already resolved, and no point
|
|
926
|
+
# recomputing parent_intended once parent_file has resolved (it's
|
|
927
|
+
# only ever consulted as parent_file's own fallback, never both).
|
|
928
|
+
if parent_file is None and parent_intended is None and search_paths:
|
|
929
|
+
parent_file = self._find_file(
|
|
930
|
+
parent_name + ".lvclass", search_paths, lvclass_path.parent
|
|
931
|
+
)
|
|
932
|
+
if parent_file is None and parent_intended is None and search_paths:
|
|
933
|
+
# No configured vilib_root — map <vilib> onto the first search
|
|
934
|
+
# root instead, so an absent parent still gets a deterministic
|
|
935
|
+
# (pure path math, no scan) intended path for web staging to
|
|
936
|
+
# name.
|
|
937
|
+
parent_intended = dep_ref.resolve_against(
|
|
938
|
+
lvclass_path, vilib_root=search_paths[0]
|
|
939
|
+
)
|
|
940
|
+
return parent_file, parent_intended
|
|
941
|
+
|
|
844
942
|
def _resolve_parent(
|
|
845
|
-
self, cls: LVClass, lvclass_path: Path
|
|
943
|
+
self, cls: LVClass, lvclass_path: Path, search_paths: list[Path]
|
|
846
944
|
) -> tuple[Path | None, Path | None]:
|
|
847
945
|
"""The parent class's file (when present) and its INTENDED path
|
|
848
946
|
(present or not) -> ``(parent_file, parent_intended)``.
|
|
849
947
|
|
|
850
948
|
PREFERS the parent's own recorded URL (a DIRECT relative path — the
|
|
851
949
|
parent commonly lives in a sibling subtree an up-tree walk can't
|
|
852
|
-
reach, e.g. ``../../Layer/Layer.lvclass``)
|
|
853
|
-
|
|
854
|
-
|
|
950
|
+
reach, e.g. ``../../Layer/Layer.lvclass``) — UNLESS that URL is
|
|
951
|
+
itself ``<vilib>``-rooted (``cls.is_vilib_parent``, e.g.
|
|
952
|
+
``"/<vilib>/ActorFramework/Actor/Actor.lvclass"``, verified against
|
|
953
|
+
Event Receiver Actor.lvclass's real ``Parent`` Item — a LEADING
|
|
954
|
+
SLASH, the marker, then forward-slash path components, NOT a normal
|
|
955
|
+
relative path), in which case it's tokenized and resolved via
|
|
956
|
+
``_resolve_vilib_class_ref`` like any other vi.lib reference (issue
|
|
957
|
+
#84's #F1 correction — the naive join used to leave a literal
|
|
958
|
+
``<vilib>`` path component that never exists).
|
|
959
|
+
|
|
960
|
+
When there's no URL but the parent's binary link record is
|
|
961
|
+
``<vilib>``-rooted (``cls.parent_link_path``, issue #84 — e.g.
|
|
962
|
+
``["<vilib>", "ActorFramework", "Actor", "Actor.lvclass"]``),
|
|
963
|
+
resolves it the SAME way via ``_resolve_vilib_class_ref``.
|
|
964
|
+
|
|
965
|
+
A NON-vilib link record (the "in-repo" PTH0 shape — no recorded
|
|
966
|
+
URL, parent lives elsewhere in the same tree) is deliberately left
|
|
967
|
+
to the existing bare-name walk-up below — ``resolve_against``'s
|
|
968
|
+
generic (non-``<vilib>``) branch reads leading EMPTY tokens as
|
|
969
|
+
``..`` hops, a shape not verified against a real in-repo PTH0
|
|
970
|
+
record, so this stays scoped to what issue #84 actually asked for
|
|
971
|
+
rather than risking the already-working walk-up.
|
|
972
|
+
|
|
973
|
+
Falls back to a bare-name walk-up (``_walk_up_find`` —
|
|
974
|
+
filesystem-only, no search_paths, so it can't reach a cross-subtree
|
|
975
|
+
or vi.lib parent) when NEITHER a URL nor a resolved vilib link path
|
|
976
|
+
was found. Both None when the class has no parent (or its parent is
|
|
977
|
+
the root ``LabVIEW Object``).
|
|
855
978
|
"""
|
|
856
979
|
parent = cls.parent_class
|
|
857
980
|
parent_file: Path | None = None
|
|
858
981
|
parent_intended: Path | None = None
|
|
859
982
|
if parent and parent != "LabVIEW Object":
|
|
860
|
-
if cls.parent_url:
|
|
983
|
+
if cls.parent_url and cls.is_vilib_parent:
|
|
984
|
+
tokens = [t for t in cls.parent_url.split("/") if t]
|
|
985
|
+
parent_file, parent_intended = self._resolve_vilib_class_ref(
|
|
986
|
+
parent, tokens, lvclass_path, search_paths
|
|
987
|
+
)
|
|
988
|
+
elif cls.parent_url:
|
|
861
989
|
# LabVIEW ``.lvclass`` URLs are relative to the class FILE
|
|
862
990
|
# treated as a directory (members read ``../X.vi``), so
|
|
863
991
|
# resolve against ``lvclass_path`` itself — that absorbs the
|
|
@@ -865,6 +993,10 @@ class LoadingMixin:
|
|
|
865
993
|
parent_intended = (lvclass_path / cls.parent_url).resolve()
|
|
866
994
|
if parent_intended.exists():
|
|
867
995
|
parent_file = parent_intended
|
|
996
|
+
elif cls.is_vilib_parent and cls.parent_link_path:
|
|
997
|
+
parent_file, parent_intended = self._resolve_vilib_class_ref(
|
|
998
|
+
parent, cls.parent_link_path, lvclass_path, search_paths
|
|
999
|
+
)
|
|
868
1000
|
if parent_file is None and parent_intended is None:
|
|
869
1001
|
parent_file = self._walk_up_find(
|
|
870
1002
|
lvclass_path.parent, parent + ".lvclass"
|
|
@@ -1105,6 +1237,7 @@ class LoadingMixin:
|
|
|
1105
1237
|
main_xml: Path | None,
|
|
1106
1238
|
search_paths: list[Path],
|
|
1107
1239
|
visited: set[str],
|
|
1240
|
+
*,
|
|
1108
1241
|
source_dir: Path | None = None,
|
|
1109
1242
|
source_override: Path | None = None,
|
|
1110
1243
|
mode: LoadMode = LoadMode.FULL,
|
|
@@ -1136,6 +1269,9 @@ class LoadingMixin:
|
|
|
1136
1269
|
bd_xml=bd_xml,
|
|
1137
1270
|
fp_xml=fp_xml if fp_xml and fp_xml.exists() else None,
|
|
1138
1271
|
main_xml=main_xml if main_xml and main_xml.exists() else None,
|
|
1272
|
+
# Pin the parser's identity (name, source_path, warnings) to the
|
|
1273
|
+
# real source path, not the fixed ``vi_BDHb.xml`` cache name.
|
|
1274
|
+
source_override=source_override,
|
|
1139
1275
|
layout=self._want_layout,
|
|
1140
1276
|
)
|
|
1141
1277
|
)
|
|
@@ -1145,7 +1281,19 @@ class LoadingMixin:
|
|
|
1145
1281
|
fp = vi.front_panel
|
|
1146
1282
|
conpane = vi.connector_pane
|
|
1147
1283
|
|
|
1148
|
-
|
|
1284
|
+
# The VI's real unqualified name comes from its SOURCE path when we have
|
|
1285
|
+
# one (``source_override``), NOT from the extracted BD XML filename: the
|
|
1286
|
+
# managed extraction cache names every artifact ``vi_BDHb.xml`` (a bounded
|
|
1287
|
+
# fixed name — see ``extractor.extract_vi_xml``), so deriving the name from
|
|
1288
|
+
# the XML would make every VI ``vi.vi``. The source path is authoritative
|
|
1289
|
+
# and is threaded here for the top-level VI (``load_vi``) and every SubVI
|
|
1290
|
+
# dependency (``_leaf_load_vi``). Only a raw ``*_BDHb.xml`` handed in
|
|
1291
|
+
# directly (no source path) falls back to the XML-derived name.
|
|
1292
|
+
unqualified_name = (
|
|
1293
|
+
source_override.name
|
|
1294
|
+
if source_override is not None
|
|
1295
|
+
else bd_xml.name.replace("_BDHb.xml", ".vi")
|
|
1296
|
+
)
|
|
1149
1297
|
# own_qname is this VI's (possibly NON-unique) qualified name — kept only
|
|
1150
1298
|
# for the self-dependency compare below and the qname reverse index. It
|
|
1151
1299
|
# is NOT the identity: two on-disk copies (a source VI + its stripped
|
|
@@ -1639,19 +1787,19 @@ class LoadingMixin:
|
|
|
1639
1787
|
owner_chain = parts[:-1] if len(parts) > 1 else None
|
|
1640
1788
|
# MINIMAL: field-load the class (no method bodies) — enough for
|
|
1641
1789
|
# by-name field names. FULL: load its whole method tree for codegen.
|
|
1642
|
-
|
|
1790
|
+
loaded_key = self.load_lvclass(
|
|
1643
1791
|
resolved,
|
|
1644
1792
|
mode,
|
|
1645
1793
|
search_paths=search_paths,
|
|
1646
1794
|
owner_chain=owner_chain,
|
|
1647
1795
|
)
|
|
1648
1796
|
if caller_qname:
|
|
1649
|
-
self._dep_graph.add_edge(caller_qname,
|
|
1797
|
+
self._dep_graph.add_edge(caller_qname, loaded_key)
|
|
1650
1798
|
# See the walk-up branch above: alias rather than let a
|
|
1651
1799
|
# differently-cased reference create a second, empty dep_graph
|
|
1652
1800
|
# node that shadows the real (populated) one.
|
|
1653
|
-
if qualified_name !=
|
|
1654
|
-
self._qualified_aliases[qualified_name] =
|
|
1801
|
+
if qualified_name != loaded_key:
|
|
1802
|
+
self._qualified_aliases[qualified_name] = loaded_key
|
|
1655
1803
|
elif leaf.endswith(".lvlib"):
|
|
1656
1804
|
lib_key = self.load_lvlib(resolved, mode, search_paths=search_paths)
|
|
1657
1805
|
if caller_qname:
|
|
@@ -1711,6 +1859,10 @@ class LoadingMixin:
|
|
|
1711
1859
|
search_paths=search_paths,
|
|
1712
1860
|
visited=set(),
|
|
1713
1861
|
source_dir=resolved.parent,
|
|
1862
|
+
# ``resolved`` is this SubVI's real source ``.vi`` path — pin the
|
|
1863
|
+
# VI's identity (key + unqualified name) to it, never to the
|
|
1864
|
+
# fixed-name ``vi_BDHb.xml`` in the extraction cache.
|
|
1865
|
+
source_override=resolved,
|
|
1714
1866
|
mode=child_mode,
|
|
1715
1867
|
)
|
|
1716
1868
|
if loaded_name:
|
|
@@ -158,17 +158,18 @@ class PrimitiveNode(GraphNode):
|
|
|
158
158
|
# reference terminal, but this structural id list always can. See
|
|
159
159
|
# ``op_walk.correlate_property_terminals``.
|
|
160
160
|
property_value_terminal_ids: list[str] = []
|
|
161
|
-
# Property node only: the BOUND front-panel control's own ddo uid
|
|
162
|
-
# unqualified -- not this node's own qualified id) when this
|
|
163
|
-
#
|
|
164
|
-
# "Abort" boolean property node
|
|
165
|
-
# a wired reference). See
|
|
166
|
-
#
|
|
167
|
-
#
|
|
161
|
+
# Property/Invoke node only: the BOUND front-panel control's own ddo uid
|
|
162
|
+
# (RAW, unqualified -- not this node's own qualified id) when this node
|
|
163
|
+
# is IMPLICIT (permanently tied to a specific control, e.g. GTR's
|
|
164
|
+
# "Abort" boolean property node or its "Test Hierarchy Tree" invoke
|
|
165
|
+
# node) -- "" for an EXPLICIT one (identity from a wired reference). See
|
|
166
|
+
# ``parser.node_types.PropertyNode``/``InvokeNode``'s class docstrings
|
|
167
|
+
# for the full heap discriminator (a direct ``<ddo>`` child + a
|
|
168
|
+
# ``<label>`` naming the control, both absent when explicit).
|
|
168
169
|
bound_control_uid: str = ""
|
|
169
170
|
# The bound control's reconstructed LVType (``parser.fp_heap_type.
|
|
170
171
|
# reconstruct_control_lvtype``, resolved at PARSE time against the
|
|
171
|
-
# front-panel heap -- see ``parser.vi.
|
|
172
|
+
# front-panel heap -- see ``parser.vi._resolve_bound_control_types``).
|
|
172
173
|
# None for an explicit node, or an implicit one whose control class isn't
|
|
173
174
|
# modeled by that reconstructor.
|
|
174
175
|
bound_control_type: LVType | None = None
|
|
@@ -47,18 +47,27 @@ PARALLEL_THRESHOLD = 50
|
|
|
47
47
|
# process-pool scheduling/pickling overhead across many small XML files.
|
|
48
48
|
_BATCH_SIZE = 20
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
# (vi_path, bd_xml, fp_xml, main_xml): vi_path is the REAL source .vi, carried so
|
|
51
|
+
# the worker can pin the parser's identity to it — the managed cache names BD XML
|
|
52
|
+
# ``vi_BDHb.xml`` (a bounded fixed name), so parsing without the real path would
|
|
53
|
+
# label every VI ``vi.vi`` (see parse_vi's source_override).
|
|
54
|
+
_ParseItem = tuple[Path, Path, Path | None, Path | None]
|
|
51
55
|
|
|
52
56
|
|
|
53
57
|
def _parse_batch(items: list[_ParseItem]) -> dict[str, ParsedVI]:
|
|
54
|
-
"""Worker entry point: parse a batch of (bd_xml, fp_xml, main_xml)
|
|
55
|
-
|
|
58
|
+
"""Worker entry point: parse a batch of (vi_path, bd_xml, fp_xml, main_xml)
|
|
59
|
+
tuples. Runs in a worker process. A single unparseable VI is skipped,
|
|
56
60
|
not fatal to the rest of the batch -- the caller's serial path parses it
|
|
57
61
|
(and reports its error, same as today) when it finds no cache entry."""
|
|
58
62
|
out: dict[str, ParsedVI] = {}
|
|
59
|
-
for bd_xml, fp_xml, main_xml in items:
|
|
63
|
+
for vi_path, bd_xml, fp_xml, main_xml in items:
|
|
60
64
|
try:
|
|
61
|
-
out[str(bd_xml)] = parse_vi(
|
|
65
|
+
out[str(bd_xml)] = parse_vi(
|
|
66
|
+
bd_xml=bd_xml,
|
|
67
|
+
fp_xml=fp_xml,
|
|
68
|
+
main_xml=main_xml,
|
|
69
|
+
source_override=vi_path,
|
|
70
|
+
)
|
|
62
71
|
except Exception:
|
|
63
72
|
logger.debug("parallel parse: skipping %s", bd_xml, exc_info=True)
|
|
64
73
|
return out
|
|
@@ -93,7 +102,7 @@ def parallel_parse_directory(
|
|
|
93
102
|
except Exception:
|
|
94
103
|
# Extraction failure -- let the serial path hit (and report) it.
|
|
95
104
|
continue
|
|
96
|
-
resolved.append((bd_xml, fp_xml, main_xml))
|
|
105
|
+
resolved.append((vi_path, bd_xml, fp_xml, main_xml))
|
|
97
106
|
|
|
98
107
|
if not resolved:
|
|
99
108
|
return {}
|