Conversation
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
Still not perfect.
# Conflicts: # spicelib/editor/base_editor.py
Pending is problem with subcircuit edits.
# 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
There was a problem hiding this comment.
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.
| 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 |
There was a problem hiding this comment.
scan_eng is imported but never used in this module. Please remove the unused import to avoid lint warnings and keep dependencies clear.
| from ...editor.primitives import scan_eng, to_float | |
| from ...editor.primitives import to_float |
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>
|
here is some feedback: ParameterNotFoundError one of the unittests says: this goes back to several cases in several files: 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) |
|
base class return types mismatch 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 ? |
vscode with the standard Pylance. I use mostly standard Microsoft provided extensions. |
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.