Skip to content

Commit 0634299

Browse files
authored
Eliminate @init_in_parent (#431)
Moves the `__init__` hook into a metaclass hook on `__init__` instead of the previously explicit `@init_in_parent` decorator. Cleans up the hook logic. Deprecates `@init_in_parent`. It seems this must be an `__init__` hook of some kind, since it needs to inspect each `super().__init__` call, recursively, with the context it is called in. The `__init__` hook does double duty: - For the top-level block being elaborated, it materializes missing params with dummy values - For inner blocks, it 'wraps' arg values by creating a param based on the type annotation Internally, removes the `Block._init_param_values`, which used to be the source of truth for init values. Instead, init params have an InitParamBinding, which stores the value, if any This changes (fixes, imo) some behavior: - No longer materializes missing params except for the top-level block. Calls to blocks that are missing params will now fail, as expected. - *Expr (eg, RangeExpr, FloatExpr) are no longer allowed as annotation types, instead must use *Like (eg, RangeLike, FloatLike) Removes `@init_in_parent` in all the library code. There's a bunch. Fixes some libraries which are broken. Removes obsoleted unit tests. Adds a dead-simple LED test, probably the simplest possible circuit here. Resolves #409
1 parent d85fb6b commit 0634299

File tree

147 files changed

+322
-523
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+322
-523
lines changed

edg/BoardTop.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
class BaseBoardTop(DesignTop):
55
"""Design top with refinements for intermediate-level (0603+ SMD), hand-solderable components."""
6-
@init_in_parent
76
def __init__(self):
87
super().__init__()
98
self.refdes_prefix = self.Parameter(StringExpr())

edg/abstract_parts/AbstractAnalogSwitch.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ def __init__(self) -> None:
3737
class AnalogSwitchTree(AnalogSwitch, GeneratorBlock):
3838
"""Generates an n-ported analog switch by creating a tree of individual, smaller switches.
3939
Parameterized by the size of the element switches."""
40-
@init_in_parent
4140
def __init__(self, switch_size: IntLike = 0):
4241
super().__init__()
4342
self.switch_size = self.ArgParameter(switch_size)

edg/abstract_parts/AbstractAntenna.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
@abstract_block
88
class Antenna(Interface, Block):
9-
@init_in_parent
109
def __init__(self, frequency: RangeLike, impedance: RangeLike = Range.all(), power: RangeLike = (0, 0)*Watt):
1110
super().__init__()
1211

@@ -31,7 +30,6 @@ class TableAntenna(Antenna, PartsTableSelector, GeneratorBlock):
3130
IMPEDANCE = PartsTableColumn(Range)
3231
POWER_RATING = PartsTableColumn(Range)
3332

34-
@init_in_parent
3533
def __init__(self, *args, **kwargs):
3634
super().__init__(*args, **kwargs)
3735
self.generator_param(self.frequency, self.power, self.impedance)

edg/abstract_parts/AbstractBjt.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ def Npn(*args, **kwargs) -> 'Bjt':
4848
def Pnp(*args, **kwargs) -> 'Bjt':
4949
return Bjt(*args, **kwargs, channel='PNP')
5050

51-
@init_in_parent
5251
def __init__(self, collector_voltage: RangeLike, collector_current: RangeLike, *,
5352
gain: RangeLike = Range.all(), power: RangeLike = Range.exact(0),
5453
channel: StringLike = StringExpr()) -> None:
@@ -91,7 +90,6 @@ class TableBjt(PartsTableSelector, Bjt):
9190
POWER_RATING = PartsTableColumn(Range)
9291
CHANNEL = PartsTableColumn(str) # either 'PNP' or 'NPN'
9392

94-
@init_in_parent
9593
def __init__(self, *args, **kwargs):
9694
super().__init__(*args, **kwargs)
9795
self.generator_param(self.collector_voltage, self.collector_current, self.gain, self.power, self.channel)

edg/abstract_parts/AbstractCapacitor.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ class CapacitorStandardFootprint(StandardFootprint['Capacitor']):
8585
@abstract_block
8686
class UnpolarizedCapacitor(PassiveComponent):
8787
"""Base type for a capacitor, that defines its parameters and without ports (since capacitors can be polarized)"""
88-
@init_in_parent
8988
def __init__(self, capacitance: RangeLike, voltage: RangeLike, *,
9089
voltage_rating_derating: FloatLike = 0.5,
9190
exact_capacitance: BoolLike = False) -> None:
@@ -150,7 +149,6 @@ def parse_capacitor(cls, value: str) -> Tuple[Range, Range]:
150149
def block_from_symbol(cls, symbol_name: str, properties: Mapping[str, str]) -> 'Capacitor':
151150
return Capacitor(*cls.parse_capacitor(properties['Value']))
152151

153-
@init_in_parent
154152
def __init__(self, *args, **kwargs) -> None:
155153
super().__init__(*args, **kwargs)
156154

@@ -178,7 +176,6 @@ class TableCapacitor(PartsTableSelector, Capacitor):
178176
NOMINAL_CAPACITANCE = PartsTableColumn(float) # nominal capacitance, even with asymmetrical tolerances
179177
VOLTAGE_RATING = PartsTableColumn(Range)
180178

181-
@init_in_parent
182179
def __init__(self, *args, **kwargs):
183180
super().__init__(*args, **kwargs)
184181
self.generator_param(self.capacitance, self.voltage, self.voltage_rating_derating, self.exact_capacitance)
@@ -220,7 +217,6 @@ class TableDeratingCapacitor(TableCapacitor):
220217
DERATE_LOWEST = 0.2 # floor for maximum derating factor
221218
# LOOSELY approximated from https://www.maximintegrated.com/en/design/technical-documents/tutorials/5/5527.html
222219

223-
@init_in_parent
224220
def __init__(self, *args, single_nominal_capacitance: RangeLike = (0, 22)*uFarad, **kwargs):
225221
super().__init__(*args, **kwargs)
226222
self.single_nominal_capacitance = self.ArgParameter(single_nominal_capacitance)
@@ -292,7 +288,6 @@ class DummyCapacitorFootprint(DummyDevice, Capacitor, FootprintBlock):
292288
293289
TODO: use footprint table?
294290
"""
295-
@init_in_parent
296291
def __init__(self, footprint: StringLike = "", manufacturer: StringLike = "", part_number: StringLike = "",
297292
value: StringLike = "",
298293
*args, **kwargs):
@@ -316,7 +311,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
316311
assert symbol_name in ('Device:C', 'Device:C_Small', 'Device:C_Polarized', 'Device:C_Polarized_Small')
317312
return {'1': self.pwr, '2': self.gnd}
318313

319-
@init_in_parent
320314
def __init__(self, capacitance: RangeLike, *, exact_capacitance: BoolLike = False) -> None:
321315
super().__init__()
322316

@@ -342,7 +336,7 @@ def connected(self, gnd: Optional[Port[GroundLink]] = None, pwr: Optional[Port[V
342336
return self
343337

344338

345-
class CombinedCapacitorElement(Capacitor): # to avoid an abstract part error
339+
class CombinedCapacitorElement(Capacitor):
346340
def contents(self):
347341
super().contents()
348342
self.assign(self.actual_capacitance, self.capacitance) # fake it, since a combined capacitance is handwavey
@@ -351,11 +345,11 @@ def contents(self):
351345
class CombinedCapacitor(MultipackDevice, MultipackBlock, GeneratorBlock):
352346
"""A packed capacitor that combines multiple individual capacitors into a single component,
353347
with the sum of or taking the max of the constituent capacitances."""
354-
@init_in_parent
355348
def __init__(self, *, extend_upper: BoolLike = False) -> None:
356349
super().__init__()
357350

358-
self.elements = self.PackedPart(PackedBlockArray(CombinedCapacitorElement()))
351+
self.elements = self.PackedPart(PackedBlockArray(CombinedCapacitorElement(capacitance=RangeExpr(),
352+
voltage=RangeExpr())))
359353
self.pos = self.PackedExport(self.elements.ports_array(lambda x: x.pos))
360354
self.neg = self.PackedExport(self.elements.ports_array(lambda x: x.neg))
361355
self.capacitances = self.PackedParameter(self.elements.params_array(lambda x: x.capacitance))

edg/abstract_parts/AbstractComparator.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ def symbol_pinning(self, symbol_name: str) -> Mapping[str, BasePort]:
1414
def block_from_symbol(cls, symbol_name: str, properties: Mapping[str, str]) -> 'Comparator':
1515
return Comparator()
1616

17-
@init_in_parent
1817
def __init__(self) -> None:
1918
super().__init__()
2019

edg/abstract_parts/AbstractConnector.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ def __init__(self) -> None:
2828

2929
class RfConnectorTestPoint(BlockInterfaceMixin[RfConnector]):
3030
"""Test point mixin that allows the footprint to take a name"""
31-
@init_in_parent
3231
def __init__(self, name: StringLike):
3332
super().__init__()
3433
self.tp_name = self.ArgParameter(name)

edg/abstract_parts/AbstractCrystal.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ class CrystalStandardFootprint(StandardFootprint['Crystal']):
3333
class Crystal(DiscreteComponent, HasStandardFootprint):
3434
_STANDARD_FOOTPRINT = CrystalStandardFootprint
3535

36-
@init_in_parent
3736
def __init__(self, frequency: RangeLike) -> None:
3837
"""Discrete crystal component."""
3938
super().__init__()
@@ -60,7 +59,6 @@ class TableCrystal(PartsTableSelector, Crystal):
6059
FREQUENCY = PartsTableColumn(Range)
6160
CAPACITANCE = PartsTableColumn(float)
6261

63-
@init_in_parent
6462
def __init__(self, *args, **kwargs) -> None:
6563
"""Discrete crystal component."""
6664
super().__init__(*args, **kwargs)
@@ -78,7 +76,6 @@ def _row_generate(self, row: PartsTableRow) -> None:
7876

7977
@abstract_block_default(lambda: OscillatorCrystal)
8078
class OscillatorReference(DiscreteApplication):
81-
@init_in_parent
8279
def __init__(self, frequency: RangeLike) -> None:
8380
"""Crystal and supporting circuitry to connect it to an oscillator driver.
8481
Should include load capacitors."""

edg/abstract_parts/AbstractDevices.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
@abstract_block
66
class Battery(PowerSource):
7-
@init_in_parent
87
def __init__(self, voltage: RangeLike,
98
current: RangeLike = RangeExpr.ZERO, *,
109
capacity: FloatLike = 0.0):

edg/abstract_parts/AbstractDiodes.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ class BaseDiode(DiscreteSemiconductor, HasStandardFootprint):
4141
"""
4242
_STANDARD_FOOTPRINT = DiodeStandardFootprint
4343

44-
@init_in_parent
4544
def __init__(self) -> None:
4645
super().__init__()
4746

@@ -59,7 +58,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
5958
assert symbol_name in ('Device:D', 'Device:D_Small')
6059
return {'A': self.anode, 'K': self.cathode}
6160

62-
@init_in_parent
6361
def __init__(self, reverse_voltage: RangeLike, current: RangeLike, *,
6462
voltage_drop: RangeLike = Range.all(),
6563
reverse_recovery_time: RangeLike = Range.all()) -> None:
@@ -95,7 +93,6 @@ class TableDiode(PartsTableSelector, Diode):
9593
FORWARD_VOLTAGE = PartsTableColumn(Range) # possible forward voltage range
9694
REVERSE_RECOVERY = PartsTableColumn(Range) # possible reverse recovery time
9795

98-
@init_in_parent
9996
def __init__(self, *args, **kwargs):
10097
super().__init__(*args, **kwargs)
10198
self.generator_param(self.reverse_voltage, self.current, self.voltage_drop, self.reverse_recovery_time)
@@ -125,7 +122,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
125122
assert symbol_name in ('Device:D_Zener', 'Device:D_Zener_Small')
126123
return {'A': self.anode, 'K': self.cathode}
127124

128-
@init_in_parent
129125
def __init__(self, zener_voltage: RangeLike) -> None:
130126
super().__init__()
131127

@@ -149,7 +145,6 @@ class TableZenerDiode(PartsTableSelector, ZenerDiode):
149145
ZENER_VOLTAGE = PartsTableColumn(Range)
150146
POWER_RATING = PartsTableColumn(Range) # tolerable power
151147

152-
@init_in_parent
153148
def __init__(self, *args, **kwargs):
154149
super().__init__(*args, **kwargs)
155150
self.generator_param(self.zener_voltage)
@@ -167,7 +162,6 @@ def _row_generate(self, row: PartsTableRow) -> None:
167162
class ProtectionZenerDiode(Protection):
168163
"""Zener diode reversed across a power rail to provide transient overvoltage protection (and become an incandescent
169164
indicator on a reverse voltage)"""
170-
@init_in_parent
171165
def __init__(self, voltage: RangeLike):
172166
super().__init__()
173167

@@ -188,7 +182,6 @@ def contents(self):
188182
@deprecated("Use AnalogClampResistor, which should be cheaper and cause less signal distortion")
189183
class AnalogClampZenerDiode(Protection, KiCadImportableBlock):
190184
"""Analog overvoltage protection diode to clamp the input voltage"""
191-
@init_in_parent
192185
def __init__(self, voltage: RangeLike):
193186
super().__init__()
194187

0 commit comments

Comments
 (0)