Skip to content

New data structures1#303

Open
nunobrum wants to merge 31 commits intomainfrom
new_data_structures1
Open

New data structures1#303
nunobrum wants to merge 31 commits intomainfrom
new_data_structures1

Conversation

@nunobrum
Copy link
Copy Markdown
Owner

A more object oriented approach to the library. This addresses requests for being able to create new components on the netlist.
This also addresses the creation of the update lists when using subcircuits.
Later will add more documentation on how to create new objects from existing ones, and construct netlists.
Also, this also creates the conditions to use a more clever SPICE parser (LARK is candidate) instead of using Regexes.

Missing management of updates and updating of sub-circuits
Removing the old concept of modified_subcircuits dictionary. Now going to be managed by CircuitInstance classes and a single magic function
# Conflicts:
#	spicelib/editor/base_editor.py
# Conflicts:
#	spicelib/editor/base_editor.py
#	spicelib/editor/spice_editor.py
# Conflicts:
#	spicelib/editor/asc_editor.py
#	spicelib/editor/base_editor.py
#	spicelib/editor/base_schematic.py
#	spicelib/editor/qsch_editor.py
#	spicelib/editor/spice_editor.py
#	spicelib/editor/updates.py
#	spicelib/sim/tookit/tolerance_deviations.py
… __getattr__ dunder methods. Now using @properties instead.

Fixed almost all unittests, excepts the ones that need to be tested with a Windows installation
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the SPICE editing library toward a more object-oriented architecture, adding new parsing/data-structure layers to support hierarchical subcircuits and richer update tracking (with an eye toward swapping the parser implementation later).

Changes:

  • Introduces new core primitives/parsing modules (primitives, spice_utils, spice_components, spice_subcircuit*) to represent and manipulate netlists/subcircuits as objects.
  • Refactors editors (ASC/QSCH) and simulation toolkit code to use the new structures and update-tracking model.
  • Updates unit tests and golden files to reflect new behavior, parsing, and update semantics.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
unittests/test_spicelib.py Updates batch simulation setup/model expectations.
unittests/test_spice_editor.py Adjusts imports, update expectations, and parsing expectations for elements/params.
unittests/test_raw_write.py Modifies RAW header comparison logic in tests.
unittests/test_qsch_editor.py Renames test class and updates value expectations; update assertions currently bypassed.
unittests/test_asc_editor.py Aligns expected update types and subcircuit edit behavior with new update tracking.
unittests/golden/opamptest_output_1.net Updates expected netlist output model name.
unittests/golden/amp3_subcircuit_edits.net Updates expected formatting/output for edited subcircuit netlist.
unittests/golden/amp3_instance_edits.net Updates expected formatting/output for instance edits.
unittests/golden/all_elements_lt.net Updates expected output for special designators and formatting.
spicelib/sim/tookit/tolerance_deviations.py Refactors imports/types in tolerance deviation analysis.
spicelib/sim/tookit/sim_analysis.py Updates editor typing/imports for new subcircuit/editor model.
spicelib/sim/sim_runner.py Small formatting tweaks and update-copy condition changes.
spicelib/scripts/rawplot.py Improves printing alignment of RAW header properties.
spicelib/raw/raw_write.py Minor formatting update in RAW writer header output.
spicelib/raw/plot_data.py Moves scan_eng import and improves error message formatting.
spicelib/editor/updates.py Adds update permission enum, new update type, iteration helper, and query helper.
spicelib/editor/spice_utils.py New shared constants/regex utilities for SPICE parsing.
spicelib/editor/spice_subcircuit_instance.py New object model for subcircuit instances with update redirection/cloning behavior.
spicelib/editor/spice_subcircuit.py New hierarchical SpiceCircuit parser/writer and subcircuit manipulation layer.
spicelib/editor/spice_components.py New component parser/tokenizer and rewrite logic for preserving/updating lines.
spicelib/editor/qsch_editor.py Refactors QSCH editing to component objects and integrates update tracking.
spicelib/editor/primitives.py New shared primitives: engineering format/parse helpers and base Component/Primitive classes.
spicelib/editor/editor_errors.py New centralized custom exceptions for editor components.
spicelib/editor/base_subcircuit.py New abstract interfaces for subcircuits and subcircuit instances.
spicelib/editor/base_schematic.py Refactors schematic base to use new primitives and update tracking signals.
spicelib/editor/base_editor.py Major base editor refactor: moves helpers out, adds permissions/update semantics, path handling.
spicelib/editor/asc_editor.py Refactors ASC editor to new component model and update tracking.
examples/testfiles/sub_circuit.asc Updates example values/params to match new subcircuit edit behavior.
examples/testfiles/all_elements_lt.net Updates example comment formatting.
examples/testfiles/Batch_Test.net Updates example netlist output/model naming and metadata.
examples/testfiles/Batch_Test.asc Updates example symbol/value to match new model naming.
examples/raw_plotting.py Updates example RAW printing formatting.
doc/modules/run_simulations.rst Updates documentation string formatting in examples.
README.md Updates string formatting in examples.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread unittests/test_raw_write.py
Comment thread spicelib/editor/spice_utils.py Outdated
Comment thread spicelib/sim/tookit/sim_analysis.py Outdated
Comment thread spicelib/editor/qsch_editor.py Outdated
Comment thread spicelib/editor/asc_editor.py Outdated
Comment thread unittests/test_qsch_editor.py
Comment thread unittests/test_spice_editor.py Outdated
from ...editor.base_editor import BaseEditor, to_float
from ..run_task import RunTask
from ...editor.base_editor import BaseEditor
from ...editor.primitives import scan_eng, to_float
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scan_eng is imported but never used in this module. Please remove the unused import to avoid lint warnings and keep dependencies clear.

Suggested change
from ...editor.primitives import scan_eng, to_float
from ...editor.primitives import to_float

Copilot uses AI. Check for mistakes.
Comment thread spicelib/editor/qsch_editor.py Outdated
Comment thread spicelib/editor/qsch_editor.py
nunobrum and others added 4 commits April 26, 2026 23:21
Remove duplicate dot instruction

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Updates suggested by Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Comment thread unittests/test_qsch_editor.py Outdated
@hb020
Copy link
Copy Markdown
Collaborator

hb020 commented May 1, 2026

here is some feedback:

ParameterNotFoundError

one of the unittests says: Parameter "Parameter R not found in QSCH file" not found

this goes back to several cases in several files:
raise ParameterNotFoundError(f"Parameter .....

I propose to change the exception in accepting 2 parameters.

diff --git a/spicelib/editor/asc_editor.py b/spicelib/editor/asc_editor.py
index 17e0473..5bd040e 100644
--- a/spicelib/editor/asc_editor.py
+++ b/spicelib/editor/asc_editor.py
@@ -548,7 +548,7 @@ class AscEditor(BaseSchematic, BaseSubCircuit):
         if match:
             return match.group('value')
         else:
-            raise ParameterNotFoundError(f"Parameter {param} not found in ASC file")
+            raise ParameterNotFoundError(param, "ASC file")
 
     def set_parameter(self, param: str, value: str | int | float) -> None:
         permission = self.begin_update()
diff --git a/spicelib/editor/editor_errors.py b/spicelib/editor/editor_errors.py
index 9731b4b..0511b1a 100644
--- a/spicelib/editor/editor_errors.py
+++ b/spicelib/editor/editor_errors.py
@@ -29,9 +29,9 @@ class ComponentNotFoundError(Exception):
 
 class ParameterNotFoundError(Exception):
     """ParameterNotFound Error"""
-    def __init__(self, parameter):
-        _logger.error(f'Parameter "{parameter}" not found')
-        super().__init__(f'Parameter "{parameter}" not found')
+    def __init__(self, parameter, context):
+        _logger.error(f'Parameter "{parameter}" not found in {context}')
+        super().__init__(f'Parameter "{parameter}" not found in {context}')
 
 
 class UnrecognizedSyntaxError(Exception):
diff --git a/spicelib/editor/primitives.py b/spicelib/editor/primitives.py
index a9c047e..1070308 100644
--- a/spicelib/editor/primitives.py
+++ b/spicelib/editor/primitives.py
@@ -397,7 +397,7 @@ class Component(Primitive):
         if key in params:
             return params[key]
         else:
-            raise ParameterNotFoundError(f"Parameter '{key}' not found in component '{self.reference}'")
+            raise ParameterNotFoundError(key, f"component '{self.reference}'")
 
     def set_parameter(self, key: str, value: float | str):
         """Sets a parameter value
diff --git a/spicelib/editor/qsch_editor.py b/spicelib/editor/qsch_editor.py
index 6746285..7a5b43f 100644
--- a/spicelib/editor/qsch_editor.py
+++ b/spicelib/editor/qsch_editor.py
@@ -1078,7 +1078,7 @@ class QschEditor(BaseSchematic, BaseSubCircuit):
         if match:
             return match.group('value')
         else:
-            raise ParameterNotFoundError(f"Parameter {param} not found in QSCH file")
+            raise ParameterNotFoundError(param, "QSCH file")
 
     def set_parameter(self, param: str, value: ValueType) -> None:
         # docstring inherited from BaseEditor
diff --git a/spicelib/editor/spice_subcircuit.py b/spicelib/editor/spice_subcircuit.py
index 1d91e3c..558ca0b 100644
--- a/spicelib/editor/spice_subcircuit.py
+++ b/spicelib/editor/spice_subcircuit.py
@@ -551,7 +551,7 @@ class SpiceCircuit(BaseSubCircuit):
         if match:
             return match.group('value')
         else:
-            raise ParameterNotFoundError(param)
+            raise ParameterNotFoundError(param, "netlist")
 
     def set_parameter(self, param: str, value: Union[str, int, float]) -> None:
         """Sets the value of a parameter in the netlist. If the parameter is not found, it is added to the netlist.

DeprecationWarning

/spicelib/editor/qsch_editor.py:668: DeprecationWarning: 'count' is passed as positional argument
  new_line = re.sub(r"^\|\.(model|subckt) (\w+) (.*)",
                new_line = re.sub(r"^\|\.(model|subckt) (\w+) (.*)",
                                  fr".\1 {refdes}•\2 \3",
                                  library_name, re.MULTILINE)

should become

                new_line = re.sub(r"^\|\.(model|subckt) (\w+) (.*)",
                                  fr".\1 {refdes}•\2 \3",
                                  library_name, flags=re.MULTILINE)

@hb020
Copy link
Copy Markdown
Collaborator

hb020 commented May 1, 2026

base class return types mismatch
AscComponent get_parameters returns dict, while the base class returns OrderedDict

ERotation vs float vs int issues

There are many lint warnings around float and int that cannot be assigned to ERotation and vv. Not sure how to solve that in the best way.

@nunobrum
Copy link
Copy Markdown
Owner Author

nunobrum commented May 2, 2026

base class return types mismatch AscComponent get_parameters returns dict, while the base class returns OrderedDict

ERotation vs float vs int issues

There are many lint warnings around float and int that cannot be assigned to ERotation and vv. Not sure how to solve that in the best way.

Which LINT are you using ?

@hb020
Copy link
Copy Markdown
Collaborator

hb020 commented May 2, 2026

Which LINT are you using ?

vscode with the standard Pylance. I use mostly standard Microsoft provided extensions.
It captures a LOT of issues. Most of them are referring to the use of None in various places.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants