diff --git a/edg/BoardTop.py b/edg/BoardTop.py index cfa6c2eb9..498b26369 100644 --- a/edg/BoardTop.py +++ b/edg/BoardTop.py @@ -3,7 +3,6 @@ class BaseBoardTop(DesignTop): """Design top with refinements for intermediate-level (0603+ SMD), hand-solderable components.""" - @init_in_parent def __init__(self): super().__init__() self.refdes_prefix = self.Parameter(StringExpr()) diff --git a/edg/abstract_parts/AbstractAnalogSwitch.py b/edg/abstract_parts/AbstractAnalogSwitch.py index 22b3c152b..88915dd3b 100644 --- a/edg/abstract_parts/AbstractAnalogSwitch.py +++ b/edg/abstract_parts/AbstractAnalogSwitch.py @@ -37,7 +37,6 @@ def __init__(self) -> None: class AnalogSwitchTree(AnalogSwitch, GeneratorBlock): """Generates an n-ported analog switch by creating a tree of individual, smaller switches. Parameterized by the size of the element switches.""" - @init_in_parent def __init__(self, switch_size: IntLike = 0): super().__init__() self.switch_size = self.ArgParameter(switch_size) diff --git a/edg/abstract_parts/AbstractAntenna.py b/edg/abstract_parts/AbstractAntenna.py index 0d7d2b0d4..2aea463c1 100644 --- a/edg/abstract_parts/AbstractAntenna.py +++ b/edg/abstract_parts/AbstractAntenna.py @@ -6,7 +6,6 @@ @abstract_block class Antenna(Interface, Block): - @init_in_parent def __init__(self, frequency: RangeLike, impedance: RangeLike = Range.all(), power: RangeLike = (0, 0)*Watt): super().__init__() @@ -31,7 +30,6 @@ class TableAntenna(Antenna, PartsTableSelector, GeneratorBlock): IMPEDANCE = PartsTableColumn(Range) POWER_RATING = PartsTableColumn(Range) - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.frequency, self.power, self.impedance) diff --git a/edg/abstract_parts/AbstractBjt.py b/edg/abstract_parts/AbstractBjt.py index aa802a8b6..09dbbb534 100644 --- a/edg/abstract_parts/AbstractBjt.py +++ b/edg/abstract_parts/AbstractBjt.py @@ -48,7 +48,6 @@ def Npn(*args, **kwargs) -> 'Bjt': def Pnp(*args, **kwargs) -> 'Bjt': return Bjt(*args, **kwargs, channel='PNP') - @init_in_parent def __init__(self, collector_voltage: RangeLike, collector_current: RangeLike, *, gain: RangeLike = Range.all(), power: RangeLike = Range.exact(0), channel: StringLike = StringExpr()) -> None: @@ -91,7 +90,6 @@ class TableBjt(PartsTableSelector, Bjt): POWER_RATING = PartsTableColumn(Range) CHANNEL = PartsTableColumn(str) # either 'PNP' or 'NPN' - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.collector_voltage, self.collector_current, self.gain, self.power, self.channel) diff --git a/edg/abstract_parts/AbstractCapacitor.py b/edg/abstract_parts/AbstractCapacitor.py index 69603a8f6..2e76fe5fb 100644 --- a/edg/abstract_parts/AbstractCapacitor.py +++ b/edg/abstract_parts/AbstractCapacitor.py @@ -85,7 +85,6 @@ class CapacitorStandardFootprint(StandardFootprint['Capacitor']): @abstract_block class UnpolarizedCapacitor(PassiveComponent): """Base type for a capacitor, that defines its parameters and without ports (since capacitors can be polarized)""" - @init_in_parent def __init__(self, capacitance: RangeLike, voltage: RangeLike, *, voltage_rating_derating: FloatLike = 0.5, exact_capacitance: BoolLike = False) -> None: @@ -150,7 +149,6 @@ def parse_capacitor(cls, value: str) -> Tuple[Range, Range]: def block_from_symbol(cls, symbol_name: str, properties: Mapping[str, str]) -> 'Capacitor': return Capacitor(*cls.parse_capacitor(properties['Value'])) - @init_in_parent def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) @@ -178,7 +176,6 @@ class TableCapacitor(PartsTableSelector, Capacitor): NOMINAL_CAPACITANCE = PartsTableColumn(float) # nominal capacitance, even with asymmetrical tolerances VOLTAGE_RATING = PartsTableColumn(Range) - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.capacitance, self.voltage, self.voltage_rating_derating, self.exact_capacitance) @@ -220,7 +217,6 @@ class TableDeratingCapacitor(TableCapacitor): DERATE_LOWEST = 0.2 # floor for maximum derating factor # LOOSELY approximated from https://www.maximintegrated.com/en/design/technical-documents/tutorials/5/5527.html - @init_in_parent def __init__(self, *args, single_nominal_capacitance: RangeLike = (0, 22)*uFarad, **kwargs): super().__init__(*args, **kwargs) self.single_nominal_capacitance = self.ArgParameter(single_nominal_capacitance) @@ -292,7 +288,6 @@ class DummyCapacitorFootprint(DummyDevice, Capacitor, FootprintBlock): TODO: use footprint table? """ - @init_in_parent def __init__(self, footprint: StringLike = "", manufacturer: StringLike = "", part_number: StringLike = "", value: StringLike = "", *args, **kwargs): @@ -316,7 +311,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: assert symbol_name in ('Device:C', 'Device:C_Small', 'Device:C_Polarized', 'Device:C_Polarized_Small') return {'1': self.pwr, '2': self.gnd} - @init_in_parent def __init__(self, capacitance: RangeLike, *, exact_capacitance: BoolLike = False) -> None: super().__init__() @@ -342,7 +336,7 @@ def connected(self, gnd: Optional[Port[GroundLink]] = None, pwr: Optional[Port[V return self -class CombinedCapacitorElement(Capacitor): # to avoid an abstract part error +class CombinedCapacitorElement(Capacitor): def contents(self): super().contents() self.assign(self.actual_capacitance, self.capacitance) # fake it, since a combined capacitance is handwavey @@ -351,11 +345,11 @@ def contents(self): class CombinedCapacitor(MultipackDevice, MultipackBlock, GeneratorBlock): """A packed capacitor that combines multiple individual capacitors into a single component, with the sum of or taking the max of the constituent capacitances.""" - @init_in_parent def __init__(self, *, extend_upper: BoolLike = False) -> None: super().__init__() - self.elements = self.PackedPart(PackedBlockArray(CombinedCapacitorElement())) + self.elements = self.PackedPart(PackedBlockArray(CombinedCapacitorElement(capacitance=RangeExpr(), + voltage=RangeExpr()))) self.pos = self.PackedExport(self.elements.ports_array(lambda x: x.pos)) self.neg = self.PackedExport(self.elements.ports_array(lambda x: x.neg)) self.capacitances = self.PackedParameter(self.elements.params_array(lambda x: x.capacitance)) diff --git a/edg/abstract_parts/AbstractComparator.py b/edg/abstract_parts/AbstractComparator.py index 2d06f6ce8..6d1300ec1 100644 --- a/edg/abstract_parts/AbstractComparator.py +++ b/edg/abstract_parts/AbstractComparator.py @@ -14,7 +14,6 @@ def symbol_pinning(self, symbol_name: str) -> Mapping[str, BasePort]: def block_from_symbol(cls, symbol_name: str, properties: Mapping[str, str]) -> 'Comparator': return Comparator() - @init_in_parent def __init__(self) -> None: super().__init__() diff --git a/edg/abstract_parts/AbstractConnector.py b/edg/abstract_parts/AbstractConnector.py index 4a7496509..cc5a3c7b6 100644 --- a/edg/abstract_parts/AbstractConnector.py +++ b/edg/abstract_parts/AbstractConnector.py @@ -28,7 +28,6 @@ def __init__(self) -> None: class RfConnectorTestPoint(BlockInterfaceMixin[RfConnector]): """Test point mixin that allows the footprint to take a name""" - @init_in_parent def __init__(self, name: StringLike): super().__init__() self.tp_name = self.ArgParameter(name) diff --git a/edg/abstract_parts/AbstractCrystal.py b/edg/abstract_parts/AbstractCrystal.py index 1d7bbb745..efbf91d5e 100644 --- a/edg/abstract_parts/AbstractCrystal.py +++ b/edg/abstract_parts/AbstractCrystal.py @@ -33,7 +33,6 @@ class CrystalStandardFootprint(StandardFootprint['Crystal']): class Crystal(DiscreteComponent, HasStandardFootprint): _STANDARD_FOOTPRINT = CrystalStandardFootprint - @init_in_parent def __init__(self, frequency: RangeLike) -> None: """Discrete crystal component.""" super().__init__() @@ -60,7 +59,6 @@ class TableCrystal(PartsTableSelector, Crystal): FREQUENCY = PartsTableColumn(Range) CAPACITANCE = PartsTableColumn(float) - @init_in_parent def __init__(self, *args, **kwargs) -> None: """Discrete crystal component.""" super().__init__(*args, **kwargs) @@ -78,7 +76,6 @@ def _row_generate(self, row: PartsTableRow) -> None: @abstract_block_default(lambda: OscillatorCrystal) class OscillatorReference(DiscreteApplication): - @init_in_parent def __init__(self, frequency: RangeLike) -> None: """Crystal and supporting circuitry to connect it to an oscillator driver. Should include load capacitors.""" diff --git a/edg/abstract_parts/AbstractDevices.py b/edg/abstract_parts/AbstractDevices.py index 0552be3df..c45ca0b64 100644 --- a/edg/abstract_parts/AbstractDevices.py +++ b/edg/abstract_parts/AbstractDevices.py @@ -4,7 +4,6 @@ @abstract_block class Battery(PowerSource): - @init_in_parent def __init__(self, voltage: RangeLike, current: RangeLike = RangeExpr.ZERO, *, capacity: FloatLike = 0.0): diff --git a/edg/abstract_parts/AbstractDiodes.py b/edg/abstract_parts/AbstractDiodes.py index 2f9fcd32a..3f2d8a601 100644 --- a/edg/abstract_parts/AbstractDiodes.py +++ b/edg/abstract_parts/AbstractDiodes.py @@ -41,7 +41,6 @@ class BaseDiode(DiscreteSemiconductor, HasStandardFootprint): """ _STANDARD_FOOTPRINT = DiodeStandardFootprint - @init_in_parent def __init__(self) -> None: super().__init__() @@ -59,7 +58,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: assert symbol_name in ('Device:D', 'Device:D_Small') return {'A': self.anode, 'K': self.cathode} - @init_in_parent def __init__(self, reverse_voltage: RangeLike, current: RangeLike, *, voltage_drop: RangeLike = Range.all(), reverse_recovery_time: RangeLike = Range.all()) -> None: @@ -95,7 +93,6 @@ class TableDiode(PartsTableSelector, Diode): FORWARD_VOLTAGE = PartsTableColumn(Range) # possible forward voltage range REVERSE_RECOVERY = PartsTableColumn(Range) # possible reverse recovery time - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) 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]: assert symbol_name in ('Device:D_Zener', 'Device:D_Zener_Small') return {'A': self.anode, 'K': self.cathode} - @init_in_parent def __init__(self, zener_voltage: RangeLike) -> None: super().__init__() @@ -149,7 +145,6 @@ class TableZenerDiode(PartsTableSelector, ZenerDiode): ZENER_VOLTAGE = PartsTableColumn(Range) POWER_RATING = PartsTableColumn(Range) # tolerable power - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.zener_voltage) @@ -167,7 +162,6 @@ def _row_generate(self, row: PartsTableRow) -> None: class ProtectionZenerDiode(Protection): """Zener diode reversed across a power rail to provide transient overvoltage protection (and become an incandescent indicator on a reverse voltage)""" - @init_in_parent def __init__(self, voltage: RangeLike): super().__init__() @@ -188,7 +182,6 @@ def contents(self): @deprecated("Use AnalogClampResistor, which should be cheaper and cause less signal distortion") class AnalogClampZenerDiode(Protection, KiCadImportableBlock): """Analog overvoltage protection diode to clamp the input voltage""" - @init_in_parent def __init__(self, voltage: RangeLike): super().__init__() diff --git a/edg/abstract_parts/AbstractFerriteBead.py b/edg/abstract_parts/AbstractFerriteBead.py index f2b3ad144..ac07aa2e5 100644 --- a/edg/abstract_parts/AbstractFerriteBead.py +++ b/edg/abstract_parts/AbstractFerriteBead.py @@ -36,7 +36,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: assert symbol_name in ('Device:L_Ferrite', 'Device:L_Ferrite_Small') return {'1': self.a, '2': self.b} - @init_in_parent def __init__(self, *, current: RangeLike = RangeExpr.ZERO, hf_impedance: RangeLike = RangeExpr.ALL, dc_resistance: RangeLike = RangeExpr.ALL) -> None: @@ -73,7 +72,6 @@ class TableFerriteBead(PartsTableSelector, FerriteBead): HF_IMPEDANCE = PartsTableColumn(Range) DC_RESISTANCE = PartsTableColumn(Range) - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.current, self.hf_impedance, self.dc_resistance) @@ -97,7 +95,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: assert symbol_name in ('Device:L_Ferrite', 'Device:L_Ferrite_Small') return {'1': self.pwr_in, '2': self.pwr_out} - @init_in_parent def __init__(self, hf_impedance: RangeLike = RangeExpr.ALL, dc_resistance: RangeLike = RangeExpr.ALL) -> None: super().__init__() diff --git a/edg/abstract_parts/AbstractFets.py b/edg/abstract_parts/AbstractFets.py index b1043b76d..25ae7232b 100644 --- a/edg/abstract_parts/AbstractFets.py +++ b/edg/abstract_parts/AbstractFets.py @@ -88,7 +88,6 @@ def NFet(*args, **kwargs) -> 'Fet': def PFet(*args, **kwargs) -> 'Fet': return Fet(*args, **kwargs, channel='P') - @init_in_parent def __init__(self, drain_voltage: RangeLike, drain_current: RangeLike, *, gate_voltage: RangeLike = (0, 0), gate_threshold_voltage: RangeLike = Range.all(), rds_on: RangeLike = Range.all(), @@ -150,7 +149,6 @@ class BaseTableFet(Fet): @non_library class TableFet(PartsTableSelector, BaseTableFet): - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.drain_voltage, self.drain_current, self.gate_voltage, self.gate_threshold_voltage, @@ -195,7 +193,6 @@ def PFet(*args, **kwargs): return SwitchFet(*args, **kwargs, channel='P') - @init_in_parent def __init__(self, *, frequency: RangeLike = 0*Hertz(tol=0), drive_current: RangeLike = Range.all(), **kwargs) -> None: super().__init__(**kwargs) @@ -209,7 +206,6 @@ class TableSwitchFet(PartsTableSelector, SwitchFet, BaseTableFet): STATIC_POWER = PartsTableColumn(Range) TOTAL_POWER = PartsTableColumn(Range) - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.frequency, self.drain_voltage, self.drain_current, diff --git a/edg/abstract_parts/AbstractFuse.py b/edg/abstract_parts/AbstractFuse.py index 2307b3079..da4958d14 100644 --- a/edg/abstract_parts/AbstractFuse.py +++ b/edg/abstract_parts/AbstractFuse.py @@ -34,7 +34,6 @@ class FuseStandardFootprint(StandardFootprint['Fuse']): class Fuse(DiscreteComponent, HasStandardFootprint): _STANDARD_FOOTPRINT = FuseStandardFootprint - @init_in_parent def __init__(self, trip_current: RangeLike, *, hold_current: RangeLike = RangeExpr.ALL, voltage: RangeLike = RangeExpr.ZERO) -> None: """Model-wise, equivalent to a VoltageSource|Sink passthrough, with a trip rating.""" @@ -74,7 +73,6 @@ class SeriesPowerFuse(Protection): """Series fuse for power applications""" FUSE_TYPE = Fuse - @init_in_parent def __init__(self, trip_current: RangeLike) -> None: super().__init__() @@ -116,7 +114,6 @@ class TableFuse(PartsTableSelector, Fuse): HOLD_CURRENT = PartsTableColumn(Range) VOLTAGE_RATING = PartsTableColumn(Range) - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.trip_current, self.hold_current, self.voltage) diff --git a/edg/abstract_parts/AbstractInductor.py b/edg/abstract_parts/AbstractInductor.py index 760f3fca9..2daf424d8 100644 --- a/edg/abstract_parts/AbstractInductor.py +++ b/edg/abstract_parts/AbstractInductor.py @@ -90,7 +90,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: assert symbol_name in ('Device:L', 'Device:L_Small') return {'1': self.a, '2': self.b} - @init_in_parent def __init__(self, inductance: RangeLike, current: RangeLike = RangeExpr.ZERO, frequency: RangeLike = RangeExpr.ZERO, @@ -136,7 +135,6 @@ class TableInductor(PartsTableSelector, Inductor): CURRENT_RATING = PartsTableColumn(Range) # tolerable current DC_RESISTANCE = PartsTableColumn(Range) # actual DCR - @init_in_parent def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.generator_param(self.inductance, self.current, self.frequency, self.resistance_dc, @@ -170,7 +168,6 @@ def _row_sort_by(cls, row: PartsTableRow) -> Any: class SeriesPowerInductor(DiscreteApplication): """VoltageSource/Sink-typed series inductor for power filtering""" - @init_in_parent def __init__(self, inductance: RangeLike, current: RangeLike = RangeExpr.ZERO, frequency: RangeLike = RangeExpr.ZERO) -> None: super().__init__() diff --git a/edg/abstract_parts/AbstractLed.py b/edg/abstract_parts/AbstractLed.py index f9040aa86..06586b9ab 100644 --- a/edg/abstract_parts/AbstractLed.py +++ b/edg/abstract_parts/AbstractLed.py @@ -40,7 +40,6 @@ class Led(DiscreteSemiconductor, HasStandardFootprint): Orange: LedColor = "orange" Any: LedColor = "" - @init_in_parent def __init__(self, color: LedColorLike = Any): super().__init__() @@ -55,7 +54,6 @@ def __init__(self, color: LedColorLike = Any): class TableLed(PartsTableSelector, Led): COLOR = PartsTableColumn(str) - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.color) @@ -83,7 +81,6 @@ def __init__(self): # TODO should there be some kind of abstract LED class, that works for both high and low side? class IndicatorLed(Light): """High-side-driven (default, "common cathode") indicator LED""" - @init_in_parent def __init__(self, color: LedColorLike = Led.Any, *, current_draw: RangeLike = (1, 10)*mAmp) -> None: """Controlled LEDs, with provisions for both current source and sink configurations. signal_in is a constant-voltage digital source, so this must contain some ballast. @@ -115,7 +112,6 @@ def __init__(self, color: LedColorLike = Led.Any, *, current_draw: RangeLike = ( class IndicatorLedArray(Light, GeneratorBlock): """An array of IndicatorLed, just a convenience wrapper.""" - @init_in_parent def __init__(self, count: IntLike, color: LedColorLike = Led.Any, *, current_draw: RangeLike = (1, 10) * mAmp): super().__init__() @@ -139,7 +135,6 @@ def generate(self): @abstract_block class IndicatorSinkLed(Light, Block): """Abstract part for an low-side-driven ("common anode") indicator LED""" - @init_in_parent def __init__(self, color: LedColorLike = Led.Any, *, current_draw: RangeLike = (1, 10)*mAmp) -> None: """Controlled LEDs, with provisions for both current source and sink configurations. signal_in is a constant-voltage digital source, so this must contain some ballast. @@ -155,7 +150,6 @@ def __init__(self, color: LedColorLike = Led.Any, *, current_draw: RangeLike = ( class IndicatorSinkLedResistor(IndicatorSinkLed): """TODO: should the resistor sided-ness be configurable, eg as a generator? Similar for IndicatorLed""" - @init_in_parent def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) @@ -178,7 +172,6 @@ def __init__(self, *args, **kwargs) -> None: class IndicatorSinkLedArray(Light, GeneratorBlock): """An array of IndicatorSinkLed, just a convenience wrapper.""" - @init_in_parent def __init__(self, count: IntLike, color: LedColorLike = Led.Any, *, current_draw: RangeLike = (1, 10) * mAmp): super().__init__() @@ -201,7 +194,6 @@ def generate(self): class VoltageIndicatorLed(Light): """LED connected to a voltage rail as an indicator that there is voltage present""" - @init_in_parent def __init__(self, color: LedColorLike = Led.Any, *, current_draw: RangeLike = (1, 10)*mAmp) -> None: """ TODO: support non single color wavelength (eg, color temperature?) @@ -231,7 +223,6 @@ def __init__(self, color: LedColorLike = Led.Any, *, current_draw: RangeLike = ( # TODO should there be some kind of abstract LED class, that works for both CA and CC type LEDs? class IndicatorSinkRgbLed(Light): """Common anode indicator RGB LED""" - @init_in_parent def __init__(self, current_draw: RangeLike = (1, 10)*mAmp) -> None: """RGB LEDs, with provisions for both common-anode and common-cathode configurations. This should not contain amplifiers.""" diff --git a/edg/abstract_parts/AbstractLedDriver.py b/edg/abstract_parts/AbstractLedDriver.py index fcc1b1ce4..d7ab12448 100644 --- a/edg/abstract_parts/AbstractLedDriver.py +++ b/edg/abstract_parts/AbstractLedDriver.py @@ -6,7 +6,6 @@ class LedDriver(PowerConditioner, Interface): """Abstract current-regulated high-power LED driver. LED ports are passive and should be directly connected to the LED (or LED string).""" - @init_in_parent def __init__(self, max_current: RangeLike): super().__init__() @@ -22,7 +21,6 @@ def __init__(self, max_current: RangeLike): @deprecated("ripple should be an internal parameter") class LedDriverSwitchingConverter(BlockInterfaceMixin[LedDriver]): """LED driver mixin indicating that the LED driver is a switching converter and with a peak-peak ripple limit.""" - @init_in_parent def __init__(self, *args, ripple_limit: FloatLike = float('inf'), **kwargs): super().__init__(*args, **kwargs) self.ripple_limit = self.ArgParameter(ripple_limit) diff --git a/edg/abstract_parts/AbstractOscillator.py b/edg/abstract_parts/AbstractOscillator.py index 95cc23321..40017b9c1 100644 --- a/edg/abstract_parts/AbstractOscillator.py +++ b/edg/abstract_parts/AbstractOscillator.py @@ -6,7 +6,6 @@ @abstract_block class Oscillator(DiscreteApplication): """Device that generates a digital clock signal given power.""" - @init_in_parent def __init__(self, frequency: RangeLike) -> None: super().__init__() @@ -33,7 +32,6 @@ class TableOscillator(PartsTableSelector, Oscillator): No default footprints are provided since these may be non-standard.""" FREQUENCY = PartsTableColumn(Range) - @init_in_parent def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.generator_param(self.frequency) diff --git a/edg/abstract_parts/AbstractPowerConverters.py b/edg/abstract_parts/AbstractPowerConverters.py index bbb67d20a..a8efeb32c 100644 --- a/edg/abstract_parts/AbstractPowerConverters.py +++ b/edg/abstract_parts/AbstractPowerConverters.py @@ -20,7 +20,6 @@ class VoltageRegulator(PowerConditioner): implementations commonly have restrictions, for example linear regulators can only produce voltages lower than the input voltage. """ - @init_in_parent def __init__(self, output_voltage: RangeLike) -> None: super().__init__() @@ -98,7 +97,6 @@ class LinearRegulatorDevice(Block): """Abstract base class that provides a default model with common functionality for a linear regulator chip. Does not include supporting components like capacitors. """ - @init_in_parent def __init__(self) -> None: super().__init__() @@ -150,7 +148,6 @@ def _calculate_ripple(output_current: RangeLike, ripple_ratio: RangeLike, *, ripple_ratio_range.lower() * output_current_range.upper(), upper_ripple_limit)) - @init_in_parent def __init__(self, *args, input_ripple_limit: FloatLike = 75 * mVolt, output_ripple_limit: FloatLike = 25 * mVolt, @@ -327,7 +324,6 @@ def _ilim_expr(inductor_ilim: RangeExpr, sw_ilim: RangeExpr, inductor_iripple: R sw_ilim - (inductor_iripple.upper() / 2), Range.all()) return iout_limit_inductor.intersect(iout_limit_sw).intersect(Range.from_lower(0)) - @init_in_parent def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequency: RangeLike, output_current: RangeLike, sw_current_limits: RangeLike, *, input_voltage_ripple: FloatLike, @@ -523,7 +519,6 @@ def _calculate_parameters(cls, input_voltage: Range, output_voltage: Range, freq inductor_peak_currents=inductor_peak_currents, effective_dutycycle=effective_dutycycle) - @init_in_parent def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequency: RangeLike, output_current: RangeLike, sw_current_limits: RangeLike, *, input_voltage_ripple: FloatLike, @@ -646,7 +641,6 @@ class BuckBoostConverterPowerPath(InternalSubcircuit, GeneratorBlock): https://www.ti.com/lit/an/slva535b/slva535b.pdf Largely based on this document, the tl;dr of which is combine the buck and boost equations """ - @init_in_parent def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequency: RangeLike, output_current: RangeLike, sw_current_limits: RangeLike, *, efficiency: RangeLike = (0.8, 1.0), # from TI reference diff --git a/edg/abstract_parts/AbstractResistor.py b/edg/abstract_parts/AbstractResistor.py index c2e27d932..9fd286780 100644 --- a/edg/abstract_parts/AbstractResistor.py +++ b/edg/abstract_parts/AbstractResistor.py @@ -70,7 +70,6 @@ def parse_resistor(cls, value: str) -> Range: def block_from_symbol(cls, symbol_name: str, properties: Mapping[str, str]) -> 'Resistor': return Resistor(resistance=cls.parse_resistor(properties['Value'])) - @init_in_parent def __init__(self, resistance: RangeLike, power: RangeLike = RangeExpr.ZERO, voltage: RangeLike = RangeExpr.ZERO) -> None: super().__init__() @@ -104,7 +103,6 @@ class TableResistor(PartsTableSelector, Resistor): POWER_RATING = PartsTableColumn(Range) VOLTAGE_RATING = PartsTableColumn(Range) - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.resistance, self.power, self.voltage) @@ -129,7 +127,6 @@ def _row_sort_by(cls, row: PartsTableRow) -> Any: class PullupResistor(DiscreteApplication): """Pull-up resistor with an VoltageSink for automatic implicit connect to a Power line.""" - @init_in_parent def __init__(self, resistance: RangeLike) -> None: super().__init__() @@ -152,7 +149,6 @@ def connected(self, pwr: Optional[Port[VoltageLink]] = None, io: Optional[Port[D class PulldownResistor(DiscreteApplication): """Pull-down resistor with an VoltageSink for automatic implicit connect to a Ground line.""" - @init_in_parent def __init__(self, resistance: RangeLike) -> None: super().__init__() @@ -175,7 +171,6 @@ def connected(self, gnd: Optional[Port[GroundLink]] = None, io: Optional[Port[Di class PullupResistorArray(TypedTestPoint, GeneratorBlock): """Array of PullupResistors, sized from the port array's connections.""" - @init_in_parent def __init__(self, resistance: RangeLike): super().__init__() self.pwr = self.Port(VoltageSink.empty(), [Power]) @@ -194,7 +189,6 @@ def generate(self): class PulldownResistorArray(TypedTestPoint, GeneratorBlock): """Array of PulldownResistors, sized from the port array's connections.""" - @init_in_parent def __init__(self, resistance: RangeLike): super().__init__() self.gnd = self.Port(Ground.empty(), [Common]) @@ -213,7 +207,6 @@ def generate(self): class SeriesPowerResistor(DiscreteApplication): """Series resistor for power applications""" - @init_in_parent def __init__(self, resistance: RangeLike) -> None: super().__init__() @@ -251,7 +244,6 @@ def connected(self, pwr_in: Optional[Port[VoltageLink]] = None, pwr_out: Optiona class CurrentSenseResistor(DiscreteApplication, KiCadImportableBlock, GeneratorBlock): """Current sense resistor with a power passthrough resistor and positive and negative sense temrinals.""" - @init_in_parent def __init__(self, resistance: RangeLike, sense_in_reqd: BoolLike = True) -> None: super().__init__() @@ -302,7 +294,6 @@ class AnalogClampResistor(Protection, KiCadImportableBlock): TODO: clamp_target should be inferred from the target voltage_limits, but voltage_limits doesn't always get propagated""" - @init_in_parent def __init__(self, clamp_target: RangeLike = (0, 3)*Volt, clamp_current: RangeLike = (0.25, 2.5)*mAmp, protection_voltage: RangeLike = (0, 0)*Volt, zero_out: BoolLike = False): super().__init__() diff --git a/edg/abstract_parts/AbstractResistorArray.py b/edg/abstract_parts/AbstractResistorArray.py index 327c0186a..ecde310fc 100644 --- a/edg/abstract_parts/AbstractResistorArray.py +++ b/edg/abstract_parts/AbstractResistorArray.py @@ -53,7 +53,6 @@ class ResistorArray(MultipackDevice, MultipackBlock, HasStandardFootprint): """An n-element resistor array, where all resistors have the same resistance and power rating.""" _STANDARD_FOOTPRINT = ResistorArrayStandardFootprint - @init_in_parent def __init__(self, count: IntLike = 0) -> None: # 0 means 'size automatically' super().__init__() @@ -91,7 +90,6 @@ class TableResistorArray(PartsTableSelector, ResistorArray): POWER_RATING = PartsTableColumn(Range) COUNT = PartsTableColumn(int) - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.count, self.a.requested(), self.b.requested(), self.resistances, self.powers) diff --git a/edg/abstract_parts/AbstractSpiMemory.py b/edg/abstract_parts/AbstractSpiMemory.py index 744491088..a71e5df6d 100644 --- a/edg/abstract_parts/AbstractSpiMemory.py +++ b/edg/abstract_parts/AbstractSpiMemory.py @@ -5,7 +5,6 @@ @abstract_block class SpiMemory(Memory, Block): """Base class for SPI memory, with acceptable sizes (in bits) as a range.""" - @init_in_parent def __init__(self, size: RangeLike) -> None: super().__init__() diff --git a/edg/abstract_parts/AbstractSwitch.py b/edg/abstract_parts/AbstractSwitch.py index 440561ba3..71c779c63 100644 --- a/edg/abstract_parts/AbstractSwitch.py +++ b/edg/abstract_parts/AbstractSwitch.py @@ -11,7 +11,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: assert symbol_name == 'Switch:SW_SPST' return {'1': self.sw, '2': self.com} - @init_in_parent def __init__(self, voltage: RangeLike, current: RangeLike = 0*Amp(tol=0)) -> None: super().__init__() @@ -36,7 +35,6 @@ class MechanicalKeyswitch(Switch): class RotaryEncoder(DiscreteComponent): """Rotary encoder with discrete clicks and a quadrature signal (A/B/Common). Includes shaft-type encoders as well as thumbwheels.""" - @init_in_parent def __init__(self, voltage: RangeLike, current: RangeLike = 0*Amp(tol=0)) -> None: super().__init__() @@ -60,7 +58,6 @@ def __init__(self, *args, **kwargs): @abstract_block class DirectionSwitch(DiscreteComponent): """Directional switch with a, b, c, d (clockwise) switches and common.""" - @init_in_parent def __init__(self, voltage: RangeLike, current: RangeLike = 0*Amp(tol=0)) -> None: super().__init__() diff --git a/edg/abstract_parts/AbstractTestPoint.py b/edg/abstract_parts/AbstractTestPoint.py index d3944a2c8..bdc2116a0 100644 --- a/edg/abstract_parts/AbstractTestPoint.py +++ b/edg/abstract_parts/AbstractTestPoint.py @@ -12,7 +12,6 @@ class TestPoint(InternalSubcircuit, Block): """Abstract test point that can take a name as a string, used as the footprint value. """ - @init_in_parent def __init__(self, tp_name: StringLike = "") -> None: super().__init__() self.io = self.Port(Passive(), [InOut]) @@ -22,7 +21,6 @@ def __init__(self, tp_name: StringLike = "") -> None: @non_library class BaseTypedTestPoint(TypedTestPoint, Block): """Base class with utility infrastructure for typed test points""" - @init_in_parent def __init__(self, tp_name: StringLike = "") -> None: super().__init__() self.io: Port @@ -37,7 +35,6 @@ def contents(self): @non_library class BaseRfTestPoint(TypedTestPoint, Block): """Base class with utility infrastructure for typed RF test points.""" - @init_in_parent def __init__(self, tp_name: StringLike = "") -> None: super().__init__() self.tp_name = self.ArgParameter(tp_name) @@ -89,7 +86,6 @@ def connected(self, io: Port[DigitalLink]) -> 'DigitalTestPoint': class DigitalArrayTestPoint(TypedTestPoint, GeneratorBlock): """Creates an array of Digital test points, sized from the port array's connections.""" - @init_in_parent def __init__(self, tp_name: StringLike = ''): super().__init__() self.io = self.Port(Vector(DigitalSink.empty()), [InOut]) @@ -135,7 +131,6 @@ def connected(self, io: Port[AnalogLink]) -> 'AnalogRfTestPoint': class I2cTestPoint(TypedTestPoint, Block): """Two test points for I2C SDA and SCL""" - @init_in_parent def __init__(self, tp_name: StringLike = ""): super().__init__() self.io = self.Port(I2cTarget(DigitalBidir.empty()), [InOut]) @@ -156,7 +151,6 @@ def connected(self, io: Port[I2cLink]) -> 'I2cTestPoint': class SpiTestPoint(TypedTestPoint, Block): """Test points for SPI""" - @init_in_parent def __init__(self, tp_name: StringLike = ""): super().__init__() self.io = self.Port(SpiPeripheral(DigitalBidir.empty()), [InOut]) @@ -179,7 +173,6 @@ def connected(self, io: Port[SpiLink]) -> 'SpiTestPoint': class CanControllerTestPoint(TypedTestPoint, Block): """Two test points for CAN controller-side TXD and RXD""" - @init_in_parent def __init__(self, tp_name: StringLike = ""): super().__init__() self.io = self.Port(CanPassivePort(DigitalBidir.empty()), [InOut]) @@ -200,8 +193,6 @@ def connected(self, io: Port[CanLogicLink]) -> 'CanControllerTestPoint': class CanDiffTestPoint(TypedTestPoint, Block): """Two test points for CAN differential-side canh and canl""" - - @init_in_parent def __init__(self, tp_name: StringLike = ""): super().__init__() self.io = self.Port(CanDiffPort(DigitalBidir.empty()), [InOut]) diff --git a/edg/abstract_parts/AbstractTvsDiode.py b/edg/abstract_parts/AbstractTvsDiode.py index cc7593647..7376150ba 100644 --- a/edg/abstract_parts/AbstractTvsDiode.py +++ b/edg/abstract_parts/AbstractTvsDiode.py @@ -17,7 +17,6 @@ class TvsDiode(BaseDiode): TODO: model capacitance frequency? model breakdown and clamping voltage? TODO: how does this differ from Zener diodes? """ - @init_in_parent def __init__(self, working_voltage: RangeLike, *, capacitance: RangeLike = Range.all()) -> None: super().__init__() @@ -32,7 +31,6 @@ def __init__(self, working_voltage: RangeLike, *, class ProtectionTvsDiode(Protection): """TVS diode across a power rail""" - @init_in_parent def __init__(self, working_voltage: RangeLike): super().__init__() @@ -52,7 +50,6 @@ def contents(self): class DigitalTvsDiode(Protection): """TVS diode protecting a signal line""" - @init_in_parent def __init__(self, working_voltage: RangeLike, *, capacitance: RangeLike = Range.all()): super().__init__() diff --git a/edg/abstract_parts/Categories.py b/edg/abstract_parts/Categories.py index 7d3a3fb06..cfe2e33ab 100644 --- a/edg/abstract_parts/Categories.py +++ b/edg/abstract_parts/Categories.py @@ -347,7 +347,6 @@ class DummyDevice(InternalBlock): class IdealModel(InternalBlock): """Ideal model device that can be used as a placeholder to get a design compiling but has no physical implementation.""" - @init_in_parent def __init__(self, *args, allow_ideal: BoolLike = False, **kwargs): super().__init__(*args, **kwargs) self.allow_ideal = self.ArgParameter(allow_ideal) diff --git a/edg/abstract_parts/CustomDiode.py b/edg/abstract_parts/CustomDiode.py index b8a066ee7..407a31842 100644 --- a/edg/abstract_parts/CustomDiode.py +++ b/edg/abstract_parts/CustomDiode.py @@ -3,7 +3,6 @@ class CustomDiode(Diode, FootprintBlock, GeneratorBlock): - @init_in_parent def __init__(self, *args, footprint_spec: StringLike = "", manufacturer_spec: StringLike = "", part_spec: StringLike = "", **kwargs): super().__init__(*args, **kwargs) diff --git a/edg/abstract_parts/CustomFet.py b/edg/abstract_parts/CustomFet.py index c586bae45..bf6de3df0 100644 --- a/edg/abstract_parts/CustomFet.py +++ b/edg/abstract_parts/CustomFet.py @@ -3,7 +3,6 @@ class CustomFet(SwitchFet, FootprintBlock, GeneratorBlock): - @init_in_parent def __init__(self, *args, footprint_spec: StringLike = "", manufacturer_spec: StringLike = "", part_spec: StringLike = "", **kwargs): super().__init__(*args, **kwargs) diff --git a/edg/abstract_parts/DigitalAmplifiers.py b/edg/abstract_parts/DigitalAmplifiers.py index bf5617002..5af48cfd9 100644 --- a/edg/abstract_parts/DigitalAmplifiers.py +++ b/edg/abstract_parts/DigitalAmplifiers.py @@ -14,7 +14,6 @@ class HighSideSwitch(PowerSwitch, KiCadSchematicBlock, GeneratorBlock): TODO: clamp_voltage should be compared against the actual voltage so the clamp is automatically generated, but generators don't support link terms (yet?)""" - @init_in_parent def __init__(self, pull_resistance: RangeLike = 10000*Ohm(tol=0.05), max_rds: FloatLike = 1*Ohm, frequency: RangeLike = RangeExpr.ZERO, *, clamp_voltage: RangeLike = RangeExpr.ZERO, clamp_resistance_ratio: FloatLike = 10) -> None: @@ -105,7 +104,6 @@ def generate(self): class OpenDrainDriver(PowerSwitch, Block): """NFET configured as an open-drain driver. Potentially useful for voltage translation applications.""" - @init_in_parent def __init__(self, max_rds: FloatLike = 1*Ohm, frequency: RangeLike = RangeExpr.ZERO) -> None: super().__init__() diff --git a/edg/abstract_parts/DummyDevices.py b/edg/abstract_parts/DummyDevices.py index ac6cb96b3..815f44c1f 100644 --- a/edg/abstract_parts/DummyDevices.py +++ b/edg/abstract_parts/DummyDevices.py @@ -17,7 +17,6 @@ def __init__(self) -> None: class DummyVoltageSource(DummyDevice): - @init_in_parent def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, current_limits: RangeLike = RangeExpr.ALL) -> None: super().__init__() @@ -32,7 +31,6 @@ def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, class DummyVoltageSink(DummyDevice): - @init_in_parent def __init__(self, voltage_limit: RangeLike = RangeExpr.ALL, current_draw: RangeLike = RangeExpr.ZERO) -> None: super().__init__() @@ -46,7 +44,6 @@ def __init__(self, voltage_limit: RangeLike = RangeExpr.ALL, class DummyDigitalSource(DummyDevice): - @init_in_parent def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, current_limits: RangeLike = RangeExpr.ALL) -> None: super().__init__() @@ -58,7 +55,6 @@ def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, class DummyDigitalSink(DummyDevice): - @init_in_parent def __init__(self, voltage_limit: RangeLike = RangeExpr.ALL, current_draw: RangeLike = RangeExpr.ZERO) -> None: super().__init__() @@ -70,7 +66,6 @@ def __init__(self, voltage_limit: RangeLike = RangeExpr.ALL, class DummyAnalogSource(DummyDevice): - @init_in_parent def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, signal_out: RangeLike = RangeExpr.EMPTY, current_limits: RangeLike = RangeExpr.ALL, @@ -86,7 +81,6 @@ def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, class DummyAnalogSink(DummyDevice): - @init_in_parent def __init__(self, voltage_limit: RangeLike = RangeExpr.ALL, signal_limit: RangeLike = RangeExpr.ALL, current_draw: RangeLike = RangeExpr.ZERO, @@ -103,7 +97,6 @@ def __init__(self, voltage_limit: RangeLike = RangeExpr.ALL, class ForcedVoltageCurrentDraw(DummyDevice, NetBlock): """Forces some input current draw regardless of the output's actual current draw value""" - @init_in_parent def __init__(self, forced_current_draw: RangeLike) -> None: super().__init__() @@ -120,7 +113,6 @@ def __init__(self, forced_current_draw: RangeLike) -> None: class ForcedVoltageCurrentLimit(DummyDevice, NetBlock): """Forces some output current limit, which should be tighter than the input's actual current draw.""" - @init_in_parent def __init__(self, forced_current_limit: RangeLike) -> None: super().__init__() @@ -140,7 +132,6 @@ def __init__(self, forced_current_limit: RangeLike) -> None: class ForcedVoltage(DummyDevice, NetBlock): """Forces some voltage on the output regardless of the input's actual voltage. Current draw is passed through unchanged.""" - @init_in_parent def __init__(self, forced_voltage: RangeLike) -> None: super().__init__() @@ -157,7 +148,6 @@ def __init__(self, forced_voltage: RangeLike) -> None: class ForcedVoltageCurrent(DummyDevice, NetBlock): """Forces some voltage and current on the output regardless of the input's actual parameters.""" - @init_in_parent def __init__(self, forced_voltage: RangeLike, forced_current: RangeLike) -> None: super().__init__() @@ -171,7 +161,6 @@ def __init__(self, forced_voltage: RangeLike, forced_current: RangeLike) -> None class ForcedAnalogVoltage(DummyDevice, NetBlock): - @init_in_parent def __init__(self, forced_voltage: RangeLike = RangeExpr()) -> None: super().__init__() @@ -188,7 +177,6 @@ def __init__(self, forced_voltage: RangeLike = RangeExpr()) -> None: class ForcedAnalogSignal(KiCadImportableBlock, DummyDevice, NetBlock): - @init_in_parent def __init__(self, forced_signal: RangeLike = RangeExpr()) -> None: super().__init__() @@ -210,7 +198,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: class ForcedDigitalSinkCurrentDraw(DummyDevice, NetBlock): - @init_in_parent def __init__(self, forced_current_draw: RangeLike = RangeExpr()) -> None: super().__init__() diff --git a/edg/abstract_parts/GateDrivers.py b/edg/abstract_parts/GateDrivers.py index 0de07df00..6cb624268 100644 --- a/edg/abstract_parts/GateDrivers.py +++ b/edg/abstract_parts/GateDrivers.py @@ -18,7 +18,6 @@ class HalfBridgeDriver(PowerSwitch, Block): TODO: auto-generate parameters based on switching frequencies and FET parameters? """ - @init_in_parent def __init__(self, has_boot_diode: BoolLike): super().__init__() self.has_boot_diode = self.ArgParameter(has_boot_diode) diff --git a/edg/abstract_parts/GenericCapacitor.py b/edg/abstract_parts/GenericCapacitor.py index 2608ff793..32d801b2a 100644 --- a/edg/abstract_parts/GenericCapacitor.py +++ b/edg/abstract_parts/GenericCapacitor.py @@ -36,7 +36,6 @@ class GenericMlcc(Capacitor, SelectorArea, FootprintBlock, GeneratorBlock): SINGLE_CAP_MAX = 22e-6 # maximum capacitance in a single part MAX_CAP_PACKAGE = 'Capacitor_SMD:C_1206_3216Metric' # default package for largest possible capacitor - @init_in_parent def __init__(self, *args, footprint_spec: StringLike = "", derating_coeff: FloatLike = 1.0, **kwargs): """ footprint specifies an optional constraint on footprint diff --git a/edg/abstract_parts/GenericResistor.py b/edg/abstract_parts/GenericResistor.py index 1431205e0..cebd3d246 100644 --- a/edg/abstract_parts/GenericResistor.py +++ b/edg/abstract_parts/GenericResistor.py @@ -17,7 +17,6 @@ class ESeriesResistor(SelectorArea, Resistor, FootprintBlock, GeneratorBlock): """ PACKAGE_POWER: List[Tuple[float, str]] - @init_in_parent def __init__(self, *args, series: IntLike = 24, tolerance: FloatLike = 0.01, footprint_spec: StringLike = "", **kwargs): super().__init__(*args, **kwargs) diff --git a/edg/abstract_parts/IoControllerMixins.py b/edg/abstract_parts/IoControllerMixins.py index 70753420c..1a387f5d0 100644 --- a/edg/abstract_parts/IoControllerMixins.py +++ b/edg/abstract_parts/IoControllerMixins.py @@ -8,7 +8,6 @@ class WithCrystalGenerator(IoController, GeneratorBlock): """A Block generator mixin that checks if a crystal oscillator is needed, and if so generates it.""" DEFAULT_CRYSTAL_FREQUENCY: Range - @init_in_parent def __init__(self): super().__init__() self.xtal_node = self.connect() # connect this internal node to the microcontroller; this may be empty diff --git a/edg/abstract_parts/IoControllerProgramming.py b/edg/abstract_parts/IoControllerProgramming.py index f40244b29..cebfc6908 100644 --- a/edg/abstract_parts/IoControllerProgramming.py +++ b/edg/abstract_parts/IoControllerProgramming.py @@ -15,7 +15,6 @@ class IoControllerWithSwdTargetConnector(IoController, BaseIoControllerExportabl This defines the interface for the SWO and TDI pin spec (passed to the pin assignment), and instantiates a SWD target with connected power and ground. SWD must be connected by the subclass.""" - @init_in_parent def __init__(self, swd_swo_pin: StringLike = "NC", swd_tdi_pin: StringLike = "NC", swd_connect_reset: BoolLike = True): super().__init__() self.swd_swo_pin = self.ArgParameter(swd_swo_pin) diff --git a/edg/abstract_parts/LevelShifter.py b/edg/abstract_parts/LevelShifter.py index f86281d6b..d762a82e3 100644 --- a/edg/abstract_parts/LevelShifter.py +++ b/edg/abstract_parts/LevelShifter.py @@ -19,7 +19,6 @@ class BidirectionaLevelShifter(Interface, GeneratorBlock): If empty, both sides are assumed to be able to drive the shifter and must have voltages and output thresholds modeled. TODO: this mode may be brittle """ - @init_in_parent def __init__(self, lv_res: RangeLike = 4.7*kOhm(tol=0.05), hv_res: RangeLike = 4.7*kOhm(tol=0.05), src_hint: StringLike = '') -> None: super().__init__() diff --git a/edg/abstract_parts/Nonstrict3v3Compatible.py b/edg/abstract_parts/Nonstrict3v3Compatible.py index 883878e71..ab75f486b 100644 --- a/edg/abstract_parts/Nonstrict3v3Compatible.py +++ b/edg/abstract_parts/Nonstrict3v3Compatible.py @@ -6,7 +6,6 @@ class Nonstrict3v3Compatible(BlockInterfaceMixin[Block]): within the absolute maximum, setting the nonstrict_3v3_compatible parameter to True extends the modeled voltage range to 3.6v or the absolute maximum, whichever is lower. Occurs in displays.""" - @init_in_parent def __init__(self, *args, nonstrict_3v3_compatible: BoolLike = False, **kwargs): super().__init__(*args, **kwargs) self.nonstrict_3v3_compatible = self.ArgParameter(nonstrict_3v3_compatible) diff --git a/edg/abstract_parts/OpampCircuits.py b/edg/abstract_parts/OpampCircuits.py index dd72ccfa5..5aac8acac 100644 --- a/edg/abstract_parts/OpampCircuits.py +++ b/edg/abstract_parts/OpampCircuits.py @@ -87,7 +87,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: } return mapping[symbol_name] - @init_in_parent def __init__(self, amplification: RangeLike, impedance: RangeLike = (10, 100)*kOhm, *, series: IntLike = 24, tolerance: FloatLike = 0.01): # to be overridden by refinements super().__init__() @@ -221,7 +220,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: } return mapping[symbol_name] - @init_in_parent def __init__(self, ratio: RangeLike, input_impedance: RangeLike, *, series: IntLike = 24, tolerance: FloatLike = 0.01): super().__init__() @@ -334,7 +332,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: } return mapping[symbol_name] - @init_in_parent def __init__(self, factor: RangeLike, capacitance: RangeLike, *, series: IntLike = 6, tolerance: FloatLike = 0.05): super().__init__() diff --git a/edg/abstract_parts/OpampCurrentSensor.py b/edg/abstract_parts/OpampCurrentSensor.py index 77ab5ba38..a58be0277 100644 --- a/edg/abstract_parts/OpampCurrentSensor.py +++ b/edg/abstract_parts/OpampCurrentSensor.py @@ -15,7 +15,6 @@ class OpampCurrentSensor(CurrentSensor, KiCadImportableBlock, Block): Discrete diffamp circuits generally have poor accuracy as a result of resistor tolerances, including very poor common-mode rejection. """ - @init_in_parent def __init__(self, resistance: RangeLike, ratio: RangeLike, input_impedance: RangeLike): super().__init__() diff --git a/edg/abstract_parts/PartsTablePart.py b/edg/abstract_parts/PartsTablePart.py index 03a81ddbd..6c00aee5d 100644 --- a/edg/abstract_parts/PartsTablePart.py +++ b/edg/abstract_parts/PartsTablePart.py @@ -37,7 +37,6 @@ def _get_table(cls) -> PartsTable: class PartsTablePart(Block): """An interface mixin for a part that is selected from a table, defining parameters to allow manual part selection as well as matching parts.""" - @init_in_parent def __init__(self, *args, part: StringLike = "", **kwargs): super().__init__(*args, **kwargs) self.part = self.ArgParameter(part) @@ -89,7 +88,6 @@ def generate(self): @abstract_block class SelectorFootprint(PartsTablePart): """Mixin that allows a specified footprint, for Blocks that automatically select a part.""" - @init_in_parent def __init__(self, *args, footprint_spec: StringLike = "", **kwargs): super().__init__(*args, **kwargs) self.footprint_spec = self.ArgParameter(footprint_spec) # actual_footprint left to the actual footprint @@ -102,7 +100,6 @@ class PartsTableFootprintFilter(PartsTableSelector, SelectorFootprint): but an internal block is created instead.""" KICAD_FOOTPRINT = PartsTableColumn(str) - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.generator_param(self.footprint_spec) diff --git a/edg/abstract_parts/PassiveConnector.py b/edg/abstract_parts/PassiveConnector.py index df56199c7..1f4ccc66e 100644 --- a/edg/abstract_parts/PassiveConnector.py +++ b/edg/abstract_parts/PassiveConnector.py @@ -13,7 +13,6 @@ class PassiveConnector(DiscreteComponent, Block): than the maximum pin index (but can be smaller, unassigned pins are NC). The allocated pin names correlate with the footprint pin, 1-indexed (per electronics convention). It is up to the instantiating layer to set the pinmap (or allow the user to set it by refinements).""" - @init_in_parent def __init__(self, length: IntLike = 0): super().__init__() self.pins = self.Port(Vector(Passive.empty())) diff --git a/edg/abstract_parts/PassiveFilters.py b/edg/abstract_parts/PassiveFilters.py index 2302dda9f..12fbf8eea 100644 --- a/edg/abstract_parts/PassiveFilters.py +++ b/edg/abstract_parts/PassiveFilters.py @@ -9,7 +9,6 @@ class LowPassRc(AnalogFilter, Block): """Passive-typed low-pass RC specified by the resistor value (impedance) and -3dB (~70%) cutoff frequency.""" - @init_in_parent def __init__(self, impedance: RangeLike, cutoff_freq: RangeLike, voltage: RangeLike): super().__init__() self.input = self.Port(Passive.empty()) @@ -35,7 +34,6 @@ def contents(self) -> None: class PullupDelayRc(DigitalFilter, Block): """Pull-up resistor with capacitor for delay. """ - @init_in_parent def __init__(self, impedance: RangeLike, time_constant: RangeLike): super().__init__() self.pwr = self.Port(VoltageSink.empty(), [Power]) @@ -63,7 +61,6 @@ def connected(self, *, gnd: Optional[Port[GroundLink]] = None, pwr: Optional[Por class AnalogLowPassRc(DigitalFilter, Block): """Low-pass RC filter attached to an analog line. """ - @init_in_parent def __init__(self, impedance: RangeLike, cutoff_freq: RangeLike): super().__init__() self.input = self.Port(AnalogSink.empty(), [Input]) @@ -86,7 +83,6 @@ class DigitalLowPassRc(DigitalFilter, Block): """Low-pass RC filter attached to a digital line. Does not change the signal, only performs filtering """ - @init_in_parent def __init__(self, impedance: RangeLike, cutoff_freq: RangeLike): super().__init__() self.input = self.Port(DigitalSink.empty(), [Input]) @@ -110,7 +106,6 @@ class DigitalLowPassRcArray(DigitalFilter, GeneratorBlock): """Array of DigitalLowPassRc, currently takes its size from the output. TODO: properly size when either input or output is sized? """ - @init_in_parent def __init__(self, impedance: RangeLike, cutoff_freq: RangeLike): super().__init__() self.input = self.Port(Vector(DigitalSink.empty()), [Input]) @@ -140,7 +135,6 @@ class LowPassRcDac(DigitalToAnalog, Block): Lower frequencies will result in either higher impedance or larger caps. This must be manually specified, since PWM frequency data is not part of the electronics model. """ - @init_in_parent def __init__(self, impedance: RangeLike, cutoff_freq: RangeLike): super().__init__() self.input = self.Port(DigitalSink.empty(), [Input]) diff --git a/edg/abstract_parts/PinMappable.py b/edg/abstract_parts/PinMappable.py index b01ec2f15..1ca94e34c 100644 --- a/edg/abstract_parts/PinMappable.py +++ b/edg/abstract_parts/PinMappable.py @@ -12,7 +12,6 @@ class PinMappable(Block): This may simply delegate the pin mapping to an inner block, for example for a microcontroller application circuit to delegate the pin mapping to the microcontroller chip block. """ - @init_in_parent def __init__(self, pin_assigns: ArrayStringLike = []) -> None: super().__init__() self.pin_assigns = self.ArgParameter(pin_assigns) diff --git a/edg/abstract_parts/PowerCircuits.py b/edg/abstract_parts/PowerCircuits.py index d99c2afa2..ae72702ec 100644 --- a/edg/abstract_parts/PowerCircuits.py +++ b/edg/abstract_parts/PowerCircuits.py @@ -40,7 +40,6 @@ def __init__(self): @abstract_block class FetHalfBridge(HalfBridge): """Implementation of a half-bridge with two NFETs and a gate driver.""" - @init_in_parent def __init__(self, frequency: RangeLike, fet_rds: RangeLike = (0, 1)*Ohm, gate_res: RangeLike = 22*Ohm(tol=0.05)): super().__init__() @@ -158,7 +157,6 @@ class RampLimiter(KiCadSchematicBlock): Additional more complex circuits https://electronics.stackexchange.com/questions/294061/p-channel-mosfet-inrush-current-limiting """ - @init_in_parent def __init__(self, *, cgd: RangeLike = 10*nFarad(tol=0.5), target_ramp: RangeLike = 1000*Volt(tol=0.25), target_vgs: RangeLike = (4, 10)*Volt, max_rds: FloatLike = 1*Ohm, _cdiv_vgs_factor: RangeLike = (0.05, 0.75)): diff --git a/edg/abstract_parts/ResistiveDivider.py b/edg/abstract_parts/ResistiveDivider.py index 37c86315d..3df732fbd 100644 --- a/edg/abstract_parts/ResistiveDivider.py +++ b/edg/abstract_parts/ResistiveDivider.py @@ -72,7 +72,6 @@ def divider_output(cls, vtop: RangeExpr, vbot: RangeExpr, ratio: RangeExpr) -> R return RangeExpr._to_expr_type(((vtop.lower() - vbot.lower()) * ratio.lower() + vbot.lower(), (vtop.upper() - vbot.upper()) * ratio.upper() + vbot.upper())) - @init_in_parent def __init__(self, ratio: RangeLike, impedance: RangeLike, *, series: IntLike = 24, tolerance: FloatLike = 0.01) -> None: super().__init__() @@ -145,7 +144,6 @@ def symbol_pinning(self, symbol_name: str) -> Mapping[str, BasePort]: assert symbol_name == 'Device:VoltageDivider' return {'1': self.input, '2': self.output, '3': self.gnd} - @init_in_parent def __init__(self, impedance: RangeLike) -> None: super().__init__() @@ -177,7 +175,6 @@ def __init__(self, impedance: RangeLike) -> None: class VoltageDivider(Analog, BaseVoltageDivider): """Voltage divider that takes in an output voltage and parallel impedance spec, and produces an output analog signal of the appropriate magnitude (as a fraction of the input voltage)""" - @init_in_parent def __init__(self, *, output_voltage: RangeLike, impedance: RangeLike) -> None: super().__init__(impedance=impedance) self.output_voltage = self.ArgParameter(output_voltage) @@ -192,7 +189,6 @@ class VoltageSenseDivider(Analog, BaseVoltageDivider): with variable input voltage. TODO: can this be unified with VoltageDivider?""" - @init_in_parent def __init__(self, *, full_scale_voltage: RangeLike, impedance: RangeLike) -> None: super().__init__(impedance=impedance) self.full_scale_voltage = self.ArgParameter(full_scale_voltage) @@ -202,7 +198,6 @@ def __init__(self, *, full_scale_voltage: RangeLike, impedance: RangeLike) -> No class FeedbackVoltageDivider(Analog, BaseVoltageDivider): """Voltage divider that takes in a ratio and parallel impedance spec, and produces an output analog signal of the appropriate magnitude (as a fraction of the input voltage)""" - @init_in_parent def __init__(self, *, output_voltage: RangeLike, impedance: RangeLike, assumed_input_voltage: RangeLike) -> None: super().__init__(impedance=impedance) @@ -230,7 +225,6 @@ def symbol_pinning(self, symbol_name: str) -> Mapping[str, BasePort]: assert symbol_name == 'Device:VoltageDivider' return {'1': self.input, '2': self.output, '3': self.gnd} - @init_in_parent def __init__(self, ratio: RangeLike, impedance: RangeLike) -> None: super().__init__() diff --git a/edg/abstract_parts/RfNetworks.py b/edg/abstract_parts/RfNetworks.py index bbec2d761..6e38c071a 100644 --- a/edg/abstract_parts/RfNetworks.py +++ b/edg/abstract_parts/RfNetworks.py @@ -13,7 +13,6 @@ class DiscreteRfWarning(BlockInterfaceMixin[Block]): parasitics of real devices. The discrete RF library components / generators are also experimental and subject to change. They also do not adhere to the tolerance conventions of non-RF parts.""" - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.discrete_rf_warning = self.Parameter(BoolExpr(False)) @@ -76,7 +75,6 @@ def _calculate_values(cls, freq: float, z1: complex, z2: complex) -> Tuple[float lc_c = 1/(lc_l * (2*pi*2*freq)**2) return lc_l, c, lc_c - @init_in_parent def __init__(self, frequency: FloatLike, src_resistance: FloatLike, src_reactance: FloatLike, load_resistance: FloatLike, tolerance: FloatLike, voltage: RangeLike, current: RangeLike): @@ -173,7 +171,6 @@ def _calculate_values(cls, freq: float, q: float, z1: complex, z2: complex) -> T return c1, c2, l1 + l2, rv - @init_in_parent def __init__(self, frequency: RangeLike, src_resistance: FloatLike, src_reactance: FloatLike, load_resistance: FloatLike, tolerance: FloatLike, voltage: RangeLike, current: RangeLike): diff --git a/edg/abstract_parts/SelectorArea.py b/edg/abstract_parts/SelectorArea.py index 54b6b2a05..767721edb 100644 --- a/edg/abstract_parts/SelectorArea.py +++ b/edg/abstract_parts/SelectorArea.py @@ -18,7 +18,6 @@ class SelectorArea(PartsTablePart): 1812 R=23.01 C=23.4 D=23.01 2512 R=29.3376 D=29.3376 """ - @init_in_parent def __init__(self, *args, footprint_area: RangeLike = RangeExpr.ALL, **kwargs): super().__init__(*args, **kwargs) self.footprint_area = self.ArgParameter(footprint_area) diff --git a/edg/abstract_parts/TouchPad.py b/edg/abstract_parts/TouchPad.py index 2b17797d4..ddf1dbcb8 100644 --- a/edg/abstract_parts/TouchPad.py +++ b/edg/abstract_parts/TouchPad.py @@ -3,7 +3,6 @@ class FootprintToucbPad(FootprintBlock, HumanInterface): - @init_in_parent def __init__(self, touch_footprint: StringLike): super().__init__() self.pad = self.Port(TouchPadPort(), [Input]) diff --git a/edg/core/Binding.py b/edg/core/Binding.py index 14fdb90bc..0246eaf96 100644 --- a/edg/core/Binding.py +++ b/edg/core/Binding.py @@ -107,7 +107,11 @@ def expr_to_proto(self, expr: ConstraintExpr, ref_map: IdentityDict[Refable, edg class InitParamBinding(ParamBinding): - """Binding that indicates this is a parameter from an __init__ argument""" + """Binding that indicates this is a parameter from an __init__ argument. + Can optionally take a value, which would have a binding in the parent's scope.""" + def __init__(self, parent: ParamParentTypes, value: Optional[ConstraintExpr] = None): + super().__init__(parent) + self.value = value class LiteralBinding(Binding): diff --git a/edg/core/Blocks.py b/edg/core/Blocks.py index bba542c91..eae7d1174 100644 --- a/edg/core/Blocks.py +++ b/edg/core/Blocks.py @@ -430,15 +430,13 @@ def check_subexpr(expr: Union[ConstraintExpr, BasePort]) -> None: # TODO rewrit if not (block_parent is self or block_parent_parent is self): raise UnreachableParameterError(f"In {type(self)}, constraint references unreachable parameter {expr}. " - "Only own parameters, or immediate contained blocks' parameters can be accessed. " - "To pass in parameters from constructors, don't forget @init_in_parent") + "Only own parameters, or immediate contained blocks' parameters can be accessed.") elif isinstance(expr, BasePort): block_parent = cast(BaseBlock, expr._block_parent()) assert block_parent is not None if not block_parent is self or block_parent._parent is self: raise UnreachableParameterError(f"In {type(self)}, constraint references unreachable port {expr}. " - "Only own ports, or immediate contained blocks' ports can be accessed. " - "To pass in parameters from constructors, don't forget @init_in_parent") + "Only own ports, or immediate contained blocks' ports can be accessed.") for subexpr in constraint._get_exprs(): check_subexpr(subexpr) diff --git a/edg/core/ConstraintExpr.py b/edg/core/ConstraintExpr.py index c370e932b..03511f6c1 100644 --- a/edg/core/ConstraintExpr.py +++ b/edg/core/ConstraintExpr.py @@ -398,7 +398,7 @@ def _to_expr_type(cls, input: Union[RangeLike, FloatLike, IntLike]) -> RangeExpr FloatExpr._to_expr_type(input[1]) )) else: - raise TypeError(f"op arg to RangeExpr must be FloatLike, got {input} of type {type(input)}") + raise TypeError(f"op arg to RangeExpr must be RangeLike, got {input} of type {type(input)}") @classmethod def _decl_to_proto(cls) -> edgir.ValInit: diff --git a/edg/core/Core.py b/edg/core/Core.py index 8c0a413e1..5be80f322 100644 --- a/edg/core/Core.py +++ b/edg/core/Core.py @@ -143,13 +143,15 @@ def values(self) -> ValuesView[ElementType]: class ElementMeta(type): + """Hook on construction to store some metadata about its creation. + This hooks the top-level __init__ only.""" def __call__(cls, *args, **kwargs): parent = builder.get_curr_context() block_context = builder.get_enclosing_block() try: obj = type.__call__(cls, *args, **kwargs) - obj._initializer_args = (args, kwargs) - obj._lexical_parent = parent + obj._initializer_args = (args, kwargs) # stores args so it is clone-able + obj._lexical_parent = parent # stores context for error checking obj._block_context = block_context obj._post_init() finally: diff --git a/edg/core/Generator.py b/edg/core/Generator.py index 73eb2d3ac..599454368 100644 --- a/edg/core/Generator.py +++ b/edg/core/Generator.py @@ -72,7 +72,7 @@ def generator(self, fn: Callable[..., None], *reqs: Any) -> None: # type: ignor assert isinstance(req_param.binding, InitParamBinding) or \ (isinstance(req_param.binding, (AllocatedBinding, IsConnectedBinding)) and req_param.binding.src._parent is self), \ - f"generator parameter {i} {req_param} not an __init__ parameter (or missing @init_in_parent)" + f"generator parameter {i} {req_param} not an __init__ parameter" self._generator = GeneratorBlock.GeneratorRecord(fn, reqs, reqs) def generate(self): diff --git a/edg/core/HierarchyBlock.py b/edg/core/HierarchyBlock.py index b202d75ab..e39d6c531 100644 --- a/edg/core/HierarchyBlock.py +++ b/edg/core/HierarchyBlock.py @@ -1,9 +1,13 @@ from __future__ import annotations -from functools import reduce, wraps +import functools +import inspect +import warnings +from functools import reduce from typing import * from .. import edgir +from .Builder import builder from . import ArrayStringExpr, ArrayRangeExpr, ArrayFloatExpr, ArrayIntExpr, ArrayBoolExpr, ArrayBoolLike, ArrayIntLike, \ ArrayFloatLike, ArrayRangeLike, ArrayStringLike from .Array import BaseVector, Vector @@ -11,7 +15,7 @@ from .Blocks import BaseBlock, Connection, BlockElaborationState, AbstractBlockProperty from .ConstraintExpr import BoolLike, FloatLike, IntLike, RangeLike, StringLike from .ConstraintExpr import ConstraintExpr, BoolExpr, FloatExpr, IntExpr, RangeExpr, StringExpr -from .Core import Refable, non_library +from .Core import Refable, non_library, ElementMeta from .HdlUserExceptions import * from .IdentityDict import IdentityDict from .IdentitySet import IdentitySet @@ -22,108 +26,22 @@ from .BlockInterfaceMixin import BlockInterfaceMixin -InitType = TypeVar('InitType', bound=Callable[..., None]) -def init_in_parent(fn: InitType) -> InitType: - """ - This is a wrapper around any Block's __init__ that takes parameters, so arguments passed into the parameters - generate into parameter assignments in the parent Block scope. - - This also handles default values, which are generated into the Block containing the __init__. - - It is explicitly not supported for a subclass to modify the parameters passed to a super().__init__ call. - This can interact badly with refinement, since the parameters of super().__init__ could be directly assigned - in an enclosing block, yet the subclass would also re-assign the same parameter, leading to a conflicting assign. - These cases should use composition instead of inheritance, by instantiating the "super" Block and so its parameters - are not made available to the enclosing scope. - """ - import inspect - from .Builder import builder - - @wraps(fn) - def wrapped(self: Block, *args_tup, **kwargs) -> Any: - args = list(args_tup) - builder_prev = builder.get_curr_context() - builder.push_element(self) - try: - if not hasattr(self, '_init_params_value'): - self._init_params_value = {} - - for arg_index, (arg_name, arg_param) in enumerate(list(inspect.signature(fn).parameters.items())[1:]): # discard 0=self - if arg_param.kind in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD): - continue # ignore *args and **kwargs, those will get resolved at a lower level - - if arg_name in kwargs: - arg_val = kwargs[arg_name] - elif arg_index < len(args): - arg_val = args[arg_index] - elif arg_param.default is not inspect._empty: - arg_val = arg_param.default - else: - arg_val = None - - if arg_name in self._init_params_value: # if previously declared, check it is the prev param and keep as-is - (prev_param, prev_val) = self._init_params_value[arg_name] - assert prev_param is arg_val, f"in {fn}, redefinition of initializer {arg_name}={arg_val} over prior {prev_val}" - else: # not previously declared, create a new constructor parameter - if isinstance(arg_val, ConstraintExpr): - assert arg_val._is_bound() or arg_val.initializer is None,\ - f"in constructor arguments got non-bound default {arg_name}={arg_val}: " +\ - "either leave default empty or pass in a value or uninitialized type " +\ - "(eg, 2.0, FloatExpr(), but NOT FloatExpr(2.0))" - - param_model: ConstraintExpr - if arg_param.annotation in (BoolLike, "BoolLike", BoolExpr, "BoolExpr"): - param_model = BoolExpr() - elif arg_param.annotation in (IntLike, "IntLike", IntExpr, "IntExpr"): - param_model = IntExpr() - elif arg_param.annotation in (FloatLike, "FloatLike", FloatExpr, "FloatExpr"): - param_model = FloatExpr() - elif arg_param.annotation in (RangeLike, "RangeLike", RangeExpr, "RangeExpr"): - param_model = RangeExpr() - elif arg_param.annotation in (StringLike, "StringLike", StringExpr, "StringExpr"): - param_model = StringExpr() - elif arg_param.annotation in (ArrayBoolLike, "ArrayBoolLike", ArrayBoolExpr, "ArrayBoolExpr"): - param_model = ArrayBoolExpr() - elif arg_param.annotation in (ArrayIntLike, "ArrayIntLike", ArrayIntExpr, "ArrayIntExpr"): - param_model = ArrayIntExpr() - elif arg_param.annotation in (ArrayFloatLike, "ArrayFloatLike", ArrayFloatExpr, "ArrayFloatExpr"): - param_model = ArrayFloatExpr() - elif arg_param.annotation in (ArrayRangeLike, "ArrayRangeLike", ArrayRangeExpr, "ArrayRangeExpr"): - param_model = ArrayRangeExpr() - elif arg_param.annotation in (ArrayStringLike, "ArrayStringLike", ArrayStringExpr, "ArrayStringExpr"): - param_model = ArrayStringExpr() - else: - raise ValueError(f"In {fn}, unknown argument type for {arg_name}: {arg_param.annotation}") - - # Create new parameter in self, and pass through this one instead of the original - param_bound = param_model._bind(InitParamBinding(self)) - - # transform value to standaradize form to ConstraintExpr or None as needed - if isinstance(arg_val, ConstraintExpr): - if not arg_val._is_bound(): # TODO: perhaps deprecate the FloatExpr() form as an empty param? - assert arg_val.initializer is None, f"models may not be passed into __init__ {arg_name}={arg_val}" - arg_val = None - elif not isinstance(arg_val, ConstraintExpr) and arg_val is not None: - arg_val = param_model._to_expr_type(arg_val) - assert arg_val is None or type(param_model) == type(arg_val), \ - f"type mismatch for {arg_name}: argument type {type(param_model)}, argument value {type(arg_val)}" - - self._init_params_value[arg_name] = (param_bound, arg_val) - - if arg_name in kwargs: - kwargs[arg_name] = param_bound - elif arg_index < len(args): - args[arg_index] = param_bound - else: - kwargs[arg_name] = param_bound - finally: - builder.pop_to(builder_prev) +def init_in_parent(fn: Any) -> Any: + warnings.warn( + f"in {fn}, @init_in_parent is no longer needed, the annotation can be removed without replacement", + DeprecationWarning, + stacklevel=2 + ) + @functools.wraps(fn) + def wrapped(self: Block, *args, **kwargs) -> Any: + # in concept, the outer deprecation should fire, but it doesn't consistently, so this is added for redundancy + warnings.warn( + f"in {fn}, @init_in_parent is no longer needed, the annotation can be removed without replacement", + DeprecationWarning + ) return fn(self, *args, **kwargs) - - # TODO check fn is constructor? - - return cast(InitType, wrapped) + return wrapped # TODO not statically type checked, since the port may be externally facing. TODO: maybe PortTags should be bridgeable? @@ -182,21 +100,150 @@ def __iter__(self): return iter((tuple(self.blocks), self)) +class BlockMeta(ElementMeta): + """This provides a hook on __init__ that replaces argument values with empty ConstraintExpr + based on the type annotation and stores the supplied argument to the __init__ (if any) in the binding. + + The supplied argument is cast to its target type and stored in the binding, in its parent context. + The binding itself is in the new object's context. + + This performs two functions: + - Allows blocks to compile at the top-level where required parameters have no values and there is no + context that provides those values + - Standardize the type of objects passed to self.ArgParameter, so the result is properly typed. + + This is applied to every class that inherits this metaclass, and hooks every super().__init__ call.""" + + _ANNOTATION_EXPR_MAP: Dict[Any, Type[ConstraintExpr]] = { + BoolLike: BoolExpr, + "BoolLike": BoolExpr, + IntLike: IntExpr, + "IntLike": IntExpr, + FloatLike: FloatExpr, + "FloatLike": FloatExpr, + RangeLike: RangeExpr, + "RangeLike": RangeExpr, + StringLike: StringExpr, + "StringLike": StringExpr, + ArrayBoolLike: ArrayBoolExpr, + "ArrayBoolLike": ArrayBoolExpr, + ArrayIntLike: ArrayIntExpr, + "ArrayIntLike": ArrayIntExpr, + ArrayFloatLike: ArrayFloatExpr, + "ArrayFloatLike": ArrayFloatExpr, + ArrayRangeLike: ArrayRangeExpr, + "ArrayRangeLike": ArrayRangeExpr, + ArrayStringLike: ArrayStringExpr, + "ArrayStringLike": ArrayStringExpr, + } + + def __new__(cls, *args: Any, **kwargs: Any) -> Any: + new_cls = super().__new__(cls, *args, **kwargs) + + if '__init__' in new_cls.__dict__: + orig_init = new_cls.__dict__['__init__'] + + # collect and pre-process argument data + arg_data: List[Tuple[str, inspect.Parameter, Type[ConstraintExpr]]] = [] + # discard param 0 (self) + for arg_name, arg_param in list(inspect.signature(orig_init).parameters.items())[1:]: + if arg_param.kind not in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD): + param_expr_type = BlockMeta._ANNOTATION_EXPR_MAP.get(arg_param.annotation, None) + if param_expr_type is None: + raise BlockDefinitionError(new_cls, f"in {new_cls}.__init__, unknown annotation type for {arg_name}: {arg_param.annotation}") + else: + param_expr_type = ConstraintExpr # dummy placeholder + + arg_data.append((arg_name, arg_param, param_expr_type)) + + def wrapped_init(self, *args, **kwargs) -> None: + if not hasattr(self, '_init_params'): # used to communicate to the block the added init params + self._init_params = {} + + def remap_arg(arg_name: str, arg_type: Type[ConstraintExpr], arg_value: Any) -> ConstraintExpr: + if isinstance(arg_value, ConstraintExpr): + if isinstance(arg_value.binding, InitParamBinding) and arg_value.binding.parent is self: + return arg_value # pass through arg that has been previously transformed + + if isinstance(arg_value, ConstraintExpr): # otherwise, create a new arg + if arg_value._is_bound(): + typed_arg_value: Optional[ConstraintExpr] = arg_type._to_expr_type(arg_value) + elif arg_value.initializer is None: + typed_arg_value = None + else: + raise BlockDefinitionError(self, + f"in constructor arguments got non-bound value {arg_name}={arg_value}: " + \ + "either leave default empty or pass in a value or uninitialized type " + \ + "(eg, 2.0, FloatExpr(), but NOT FloatExpr(2.0))") + elif arg_value is not None: + typed_arg_value = arg_type._to_expr_type(arg_value) + else: + typed_arg_value = None + + return arg_type()._bind(InitParamBinding(self, typed_arg_value)) + + # create wrapper ConstraintExpr in new object scope + builder_prev = builder.get_curr_context() + builder.push_element(self) + try: + # rebuild args and kwargs by traversing the args list + new_args: List[Any] = [] + new_kwargs: Dict[str, Any] = {} + for arg_pos, (arg_name, arg_param, param_expr_type) in enumerate(arg_data): + if arg_param.kind == inspect.Parameter.VAR_POSITIONAL: # pass-through *args, handled at lower level + new_args.extend(args[arg_pos:]) + elif arg_param.kind == inspect.Parameter.VAR_KEYWORD: # pass-through *kwargs, handled at lower level + for arg_name in kwargs: + if arg_name not in new_kwargs: + new_kwargs[arg_name] = kwargs[arg_name] + elif arg_pos < len(args) and arg_param.kind in (inspect.Parameter.POSITIONAL_ONLY, + inspect.Parameter.POSITIONAL_OR_KEYWORD): # present positional arg + new_arg = remap_arg(arg_name, param_expr_type, args[arg_pos]) + new_args.append(new_arg) + self._init_params[arg_name] = new_arg + elif arg_pos >= len(args) and arg_param.kind in (inspect.Parameter.POSITIONAL_ONLY, ): # non-present positional arg + if len(builder.stack) == 1: # at top-level, fill in all args + new_arg = remap_arg(arg_name, param_expr_type, None) + new_args.append(new_arg) + self._init_params[arg_name] = new_arg + elif arg_name in kwargs and arg_param.kind in (inspect.Parameter.POSITIONAL_OR_KEYWORD, + inspect.Parameter.KEYWORD_ONLY): # present kwarg + new_arg = remap_arg(arg_name, param_expr_type, kwargs[arg_name]) + new_kwargs[arg_name] = new_arg + self._init_params[arg_name] = new_arg + elif arg_name not in kwargs and arg_param.kind in (inspect.Parameter.POSITIONAL_OR_KEYWORD, + inspect.Parameter.KEYWORD_ONLY): # non-present kwarg + if arg_param.default is not inspect._empty: # default values do show up in kwargs, add them to transform them + new_arg = remap_arg(arg_name, param_expr_type, arg_param.default) + new_kwargs[arg_name] = new_arg + self._init_params[arg_name] = new_arg + elif len(builder.stack) == 1: # at top-level, fill in all args + new_arg = remap_arg(arg_name, param_expr_type, None) + new_kwargs[arg_name] = new_arg + self._init_params[arg_name] = new_arg + finally: + builder.pop_to(builder_prev) + + orig_init(self, *new_args, **new_kwargs) + + new_cls.__init__ = functools.update_wrapper(wrapped_init, orig_init) + + return new_cls + + @non_library -class Block(BaseBlock[edgir.HierarchyBlock]): +class Block(BaseBlock[edgir.HierarchyBlock], metaclass=BlockMeta): """Part with a statically-defined subcircuit. Relations between contained parameters may only be expressed in the given constraint language. """ def __init__(self) -> None: super().__init__() - # name -> (empty param, default argument (if any)), set in @init_in_parent - self._init_params_value: Dict[str, Tuple[ConstraintExpr, Optional[ConstraintExpr]]] - if not hasattr(self, '_init_params_value'): - self._init_params_value = {} - for param_name, (param, param_value) in self._init_params_value.items(): - self._parameters.register(param) - self.manager.add_element(param_name, param) + if hasattr(self, '_init_params'): # used to propagate params generated in the metaclass __init__ hook + for param_name, param in cast(Dict, self._init_params).items(): + self._parameters.register(param) + self.manager.add_element(param_name, param) + delattr(self, '_init_params') self._mixins: List['BlockInterfaceMixin'] = [] @@ -224,23 +271,14 @@ def _get_ref_map(self, prefix: edgir.LocalPath) -> IdentityDict[Refable, edgir.L return ref_map - def _get_init_params_values(self) -> Dict[str, Tuple[ConstraintExpr, Optional[ConstraintExpr]]]: - if self._mixins: - combined_dict = self._init_params_value.copy() - for mixin in self._mixins: - combined_dict.update(mixin._get_init_params_values()) - return combined_dict - else: - return self._init_params_value - def _populate_def_proto_block_base(self, pb: edgir.HierarchyBlock) -> edgir.HierarchyBlock: pb = super()._populate_def_proto_block_base(pb) # generate param defaults - for param_name, (param, param_value) in self._get_init_params_values().items(): - if param_value is not None: + for param_name, param in self._parameters.items(): + if isinstance(param.binding, InitParamBinding) and param.binding.value is not None: # default values can't depend on anything so the ref_map is empty - pb.param_defaults[param_name].CopyFrom(param_value._expr_to_proto(IdentityDict())) + pb.param_defaults[param_name].CopyFrom(param.binding.value._expr_to_proto(IdentityDict())) return pb @@ -341,10 +379,13 @@ def _populate_def_proto_hierarchy(self, pb: edgir.HierarchyBlock) -> edgir.Hiera # generate block initializers for (block_name, block) in self._blocks.items(): - for (block_param_name, (block_param, block_param_value)) in block._get_init_params_values().items(): - if block_param_value is not None: + all_block_params = dict(block._parameters.items()) + for mixin in block._mixins: + all_block_params.update(mixin._parameters.items()) + for (block_param_name, block_param) in all_block_params.items(): + if isinstance(block_param.binding, InitParamBinding) and block_param.binding.value is not None: edgir.add_pair(pb.constraints, f'(init){block_name}.{block_param_name}').CopyFrom( # TODO better name - AssignBinding.make_assign(block_param, block_param._to_expr_type(block_param_value), ref_map) + AssignBinding.make_assign(block_param, block_param.binding.value, ref_map) ) return pb @@ -358,8 +399,6 @@ def _def_to_proto(self) -> edgir.HierarchyBlock: pb = self._populate_def_proto_block_base(pb) pb = self._populate_def_proto_port_init(pb) - for (name, (param, param_value)) in self._get_init_params_values().items(): - assert param.initializer is None, f"__init__ argument param {name} has unexpected initializer" pb = self._populate_def_proto_param_init(pb) pb = self._populate_def_proto_hierarchy(pb) @@ -483,7 +522,7 @@ def ArgParameter(self, param: CastableType, *, doc: Optional[str] = None) -> Con if param.binding is None: raise TypeError(f"param to ArgParameter(...) must have binding") if not isinstance(param.binding, InitParamBinding): - raise TypeError(f"param to ArgParameter(...) must be __init__ argument with @init_in_parent") + raise TypeError(f"param to ArgParameter(...) must be __init__ argument") if doc is not None: self._param_docs[param] = doc diff --git a/edg/core/test_block_errors.py b/edg/core/test_block_errors.py index 6873ea4ca..0881d32a7 100644 --- a/edg/core/test_block_errors.py +++ b/edg/core/test_block_errors.py @@ -52,26 +52,6 @@ def test_unbound_link(self) -> None: with self.assertRaises(UnconnectableError): self.NoBridgeHierarchyBlock()._elaborated_def_to_proto() - class AboveConnectBlock(Block): - """A block that directly tries to connect to a parent port (passed in through the constructor)""" - class BadInnerBlock(Block): # TODO this is kind of nasty? - def __init__(self, above_port: TestPortSource) -> None: - super().__init__() - self.connect(above_port) - assert False # the above connect should error - - def __init__(self) -> None: - super().__init__() - self.source = self.Port(TestPortSource()) - - def contents(self) -> None: - super().contents() - self.inner = self.Block(self.BadInnerBlock(self.source)) - - def test_above_connect(self) -> None: - with self.assertRaises(UnconnectableError): - self.AboveConnectBlock()._elaborated_def_to_proto() - class AmbiguousJoinBlock(Block): """A block with a connect join that merges two names""" def contents(self) -> None: @@ -86,43 +66,3 @@ def contents(self) -> None: def test_ambiguous_join(self) -> None: with self.assertRaises(UnconnectableError): self.AmbiguousJoinBlock()._elaborated_def_to_proto() - - -class InaccessibleParamTestCase(unittest.TestCase): - class BadParamReferenceBlock(Block): - """A block that tries to access deeply nested block parameters""" - class BadInnerBlock(Block): - def __init__(self, in_range: RangeExpr) -> None: - super().__init__() - self.require(in_range == (0, 1)) - - def __init__(self) -> None: - super().__init__() - self.range = self.Parameter(RangeExpr()) - - def contents(self) -> None: - super().contents() - self.inner = self.Block(self.BadInnerBlock(self.range)) - - def test_bad_param_reference(self) -> None: - with self.assertRaises(UnreachableParameterError): - self.BadParamReferenceBlock()._elaborated_def_to_proto() - - class BadParamInitBlock(Block): - """A block that does initialization without @init_in_parent""" - class BadInnerBlock(Block): - def __init__(self, in_range: RangeExpr) -> None: - super().__init__() - self.range = self.Parameter(RangeExpr(in_range)) - - def __init__(self) -> None: - super().__init__() - self.range = self.Parameter(RangeExpr()) - - def contents(self) -> None: - super().contents() - self.inner = self.Block(self.BadInnerBlock(self.range)) - - def test_bad_param_initializer(self) -> None: - with self.assertRaises(UnreachableParameterError): - self.BadParamInitBlock()._elaborated_def_to_proto() diff --git a/edg/core/test_default.py b/edg/core/test_default.py index 54bca4d2b..ff2582eb8 100644 --- a/edg/core/test_default.py +++ b/edg/core/test_default.py @@ -8,26 +8,31 @@ class BaseParamClass(Block): # Base class containing no parameters or default pass -class NondefaultParamClass(BaseParamClass): # contains a single non-default param - @init_in_parent +class NonDefaultParamClass(BaseParamClass): # contains a single param without a default + def __init__(self, nondefault_param: IntLike) -> None: + super().__init__() + + +class NonDefaultParamSubClass(BaseParamClass): # inherits defaults without adding anything + pass + + +class EmptyDefaultParamClass(BaseParamClass): # contains a single empty-default param def __init__(self, nondefault_param: IntLike = IntExpr()) -> None: super().__init__() -class DefaultParamSubClass(NondefaultParamClass): # adds a default param on top of the inherited params - @init_in_parent +class DefaultParamSubClass(EmptyDefaultParamClass): # adds a default param on top of the inherited params def __init__(self, default_param: IntLike = 42, **kwargs) -> None: super().__init__(**kwargs) class OverrideDefaultSubClass(DefaultParamSubClass): # changes the default param of the parent - @init_in_parent def __init__(self, default_param: IntLike = 16, **kwargs) -> None: super().__init__(default_param, **kwargs) class CombinedParamSubClass(DefaultParamSubClass): # adds a default param on top of the inherited params - @init_in_parent def __init__(self, nondefault_param2: FloatLike = FloatExpr(), default_param2: StringLike = "test", **kwargs) -> None: super().__init__(**kwargs) @@ -39,8 +44,18 @@ def test_base(self): self.assertEqual(len(pb.param_defaults), 0) - def test_nondefault(self): - pb = NondefaultParamClass()._elaborated_def_to_proto() + def test_non_default(self): + pb = NonDefaultParamClass()._elaborated_def_to_proto() # type: ignore + + self.assertEqual(len(pb.param_defaults), 0) + + def test_non_default_subclass(self): + pb = NonDefaultParamSubClass()._elaborated_def_to_proto() + + self.assertEqual(len(pb.param_defaults), 0) + + def test_empty_default(self): + pb = EmptyDefaultParamClass()._elaborated_def_to_proto() self.assertEqual(len(pb.param_defaults), 0) diff --git a/edg/core/test_generator.py b/edg/core/test_generator.py index 1d8504af2..d5734e34a 100644 --- a/edg/core/test_generator.py +++ b/edg/core/test_generator.py @@ -29,7 +29,6 @@ def __init__(self) -> None: class GeneratorDependency(GeneratorBlock): - @init_in_parent def __init__(self, float_preset: FloatLike) -> None: super().__init__() self.float_param = self.Parameter(FloatExpr()) @@ -47,7 +46,6 @@ def __init__(self) -> None: class GeneratorMultiParameter(GeneratorBlock): - @init_in_parent def __init__(self, float_preset1: FloatLike, float_preset2: FloatLike) -> None: super().__init__() self.float_param1 = self.Parameter(FloatExpr()) @@ -105,14 +103,12 @@ def __init__(self, range_value: RangeLike = RangeExpr()) -> None: class TestBlockSource(Block): - @init_in_parent def __init__(self, float_value: FloatLike) -> None: super().__init__() self.port = self.Port(TestPortSource(float_value)) class TestBlockSink(Block): - @init_in_parent def __init__(self, range_value: RangeLike) -> None: super().__init__() self.port = self.Port(TestPortSink(range_value)) diff --git a/edg/core/test_generator_portvector.py b/edg/core/test_generator_portvector.py index a0214feb2..3c57d0e6d 100644 --- a/edg/core/test_generator_portvector.py +++ b/edg/core/test_generator_portvector.py @@ -111,7 +111,6 @@ def test_exported_ports(self): class GeneratorArrayParam(GeneratorBlock): - @init_in_parent def __init__(self, param: ArrayRangeLike) -> None: super().__init__() self.ports = self.Port(Vector(TestPortSink())) diff --git a/edg/core/test_initializer.py b/edg/core/test_initializer.py index 51ea04a88..2eb7441e1 100644 --- a/edg/core/test_initializer.py +++ b/edg/core/test_initializer.py @@ -12,7 +12,6 @@ def __init__(self) -> None: class TestInternalBlock(Block): - @init_in_parent def __init__(self, inner_param: FloatLike = 3.0, bundle_param: FloatLike = FloatExpr()) -> None: super().__init__() self.inner_bundle = self.Port(TestBundle(bundle_param, 0, 24), optional=True) diff --git a/edg/core/test_mixin.py b/edg/core/test_mixin.py index f280cc2f3..f998b65b2 100644 --- a/edg/core/test_mixin.py +++ b/edg/core/test_mixin.py @@ -13,7 +13,6 @@ def __init__(self) -> None: class TestMixin(BlockInterfaceMixin[TestMixinBase]): - @init_in_parent def __init__(self, *args, mixin_float: FloatLike = 1.0, **kwargs) -> None: super().__init__(*args, **kwargs) self.mixin_port = self.Port(TestPortSink()) diff --git a/edg/core/test_simple_expr_eval.py b/edg/core/test_simple_expr_eval.py index 1060c5398..dbebfca0a 100644 --- a/edg/core/test_simple_expr_eval.py +++ b/edg/core/test_simple_expr_eval.py @@ -42,7 +42,6 @@ def __init__(self, range_param: RangeLike = RangeExpr()) -> None: class TestEvalPortBlock(Block): - @init_in_parent def __init__(self, range_param: RangeLike = RangeExpr()) -> None: super().__init__() self.port = self.Port(TestReductionPort(range_param)) diff --git a/edg/electronics_model/ConnectedGenerator.py b/edg/electronics_model/ConnectedGenerator.py index c5b985d67..3aa942121 100644 --- a/edg/electronics_model/ConnectedGenerator.py +++ b/edg/electronics_model/ConnectedGenerator.py @@ -26,7 +26,6 @@ class BaseConnectedGenerator(DefaultConnectionBlock, GeneratorBlock, Generic[Out INPUTS_TYPE: Type[Port] OUTPUT_TYPE: Type[Port] - @init_in_parent def __init__(self, in_is_connected: BoolLike = BoolExpr()) -> None: """in_is_connected needs to be connected from above, since from the perspective of this block, the input is always (locally) connected""" diff --git a/edg/electronics_model/DigitalPorts.py b/edg/electronics_model/DigitalPorts.py index 4b9aca5de..ac1b235ef 100644 --- a/edg/electronics_model/DigitalPorts.py +++ b/edg/electronics_model/DigitalPorts.py @@ -245,7 +245,6 @@ def contents(self) -> None: class DigitalSourceAdapterVoltageSource(CircuitPortAdapter[VoltageSource]): - @init_in_parent def __init__(self): super().__init__() self.src = self.Port(DigitalSink( # otherwise ideal diff --git a/edg/electronics_model/GroundPort.py b/edg/electronics_model/GroundPort.py index 114750333..ff120e9d8 100644 --- a/edg/electronics_model/GroundPort.py +++ b/edg/electronics_model/GroundPort.py @@ -59,7 +59,6 @@ def contents(self) -> None: class GroundAdapterVoltageSource(CircuitPortAdapter['VoltageSource']): - @init_in_parent def __init__(self): from .VoltagePorts import VoltageSource super().__init__() @@ -70,7 +69,6 @@ def __init__(self): class GroundAdapterDigitalSource(CircuitPortAdapter['DigitalSource']): - @init_in_parent def __init__(self): from .DigitalPorts import DigitalSource super().__init__() @@ -82,7 +80,6 @@ def __init__(self): class GroundAdapterAnalogSource(CircuitPortAdapter['AnalogSource']): - @init_in_parent def __init__(self): from .AnalogPort import AnalogSource diff --git a/edg/electronics_model/KiCadSchematicBlock.py b/edg/electronics_model/KiCadSchematicBlock.py index 76ba36c5e..55c2ce36d 100644 --- a/edg/electronics_model/KiCadSchematicBlock.py +++ b/edg/electronics_model/KiCadSchematicBlock.py @@ -43,7 +43,6 @@ def block_pinning(block: KiCadBlackbox) -> Mapping[str, BasePort]: return {pin: block.ports.request(pin) for pin in pin_numbers} return block_model, block_pinning - @init_in_parent def __init__(self, kicad_pins: ArrayStringLike, kicad_refdes_prefix: StringLike, kicad_footprint: StringLike, kicad_part: StringLike, kicad_value: StringLike, kicad_datasheet: StringLike): super().__init__() diff --git a/edg/electronics_model/PassivePort.py b/edg/electronics_model/PassivePort.py index ff788c893..68d883de3 100644 --- a/edg/electronics_model/PassivePort.py +++ b/edg/electronics_model/PassivePort.py @@ -18,7 +18,6 @@ def __init__(self): class PassiveAdapterGround(CircuitPortAdapter[Ground]): - @init_in_parent def __init__(self, voltage_limits: RangeLike = RangeExpr.ALL): super().__init__() self.src = self.Port(Passive()) @@ -27,7 +26,6 @@ def __init__(self, voltage_limits: RangeLike = RangeExpr.ALL): class PassiveAdapterVoltageSource(CircuitPortAdapter[VoltageSource]): # TODO we can't use **kwargs b/c init_in_parent needs the initializer list - @init_in_parent def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, current_limits: RangeLike = RangeExpr.ALL): super().__init__() @@ -36,8 +34,7 @@ def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, class PassiveAdapterVoltageSink(CircuitPortAdapter[VoltageSink]): - # TODO we can't use **kwargs b/c init_in_parent needs the initializer list - @init_in_parent + # TODO we can't use **kwargs b/c the init hook needs an initializer list def __init__(self, voltage_limits: RangeLike = RangeExpr.ALL, current_draw: RangeLike = RangeExpr.ZERO): super().__init__() @@ -46,8 +43,7 @@ def __init__(self, voltage_limits: RangeLike = RangeExpr.ALL, class PassiveAdapterDigitalSource(CircuitPortAdapter[DigitalSource]): - # TODO we can't use **kwargs b/c init_in_parent needs the initializer list - @init_in_parent + # TODO we can't use **kwargs b/c the init hook needs an initializer list def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, current_limits: RangeLike = RangeExpr.ALL, output_thresholds: RangeLike = RangeExpr.ALL, @@ -66,8 +62,7 @@ def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, class PassiveAdapterDigitalSink(CircuitPortAdapter[DigitalSink]): - # TODO we can't use **kwargs b/c init_in_parent needs the initializer list - @init_in_parent + # TODO we can't use **kwargs b/c the init hook needs an initializer list def __init__(self, voltage_limits: RangeLike = RangeExpr.ALL, current_draw: RangeLike = RangeExpr.ZERO, input_thresholds: RangeLike = RangeExpr.EMPTY, @@ -84,8 +79,7 @@ def __init__(self, voltage_limits: RangeLike = RangeExpr.ALL, class PassiveAdapterDigitalBidir(CircuitPortAdapter[DigitalBidir]): - # TODO we can't use **kwargs b/c init_in_parent needs the initializer list - @init_in_parent + # TODO we can't use **kwargs b/c the init hook needs an initializer list def __init__(self, voltage_limits: RangeLike = RangeExpr.ALL, current_draw: RangeLike = RangeExpr.ZERO, voltage_out: RangeLike = RangeExpr.ZERO, @@ -106,8 +100,7 @@ def __init__(self, voltage_limits: RangeLike = RangeExpr.ALL, class PassiveAdapterAnalogSource(CircuitPortAdapter[AnalogSource]): - # TODO we can't use **kwargs b/c init_in_parent needs the initializer list - @init_in_parent + # TODO we can't use **kwargs b/c the init hook needs an initializer list def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, signal_out: RangeLike = RangeExpr.ZERO, current_limits: RangeLike = RangeExpr.ALL, impedance: RangeLike = RangeExpr.ZERO): super().__init__() @@ -117,8 +110,7 @@ def __init__(self, voltage_out: RangeLike = RangeExpr.ZERO, signal_out: RangeLik class PassiveAdapterAnalogSink(CircuitPortAdapter[AnalogSink]): - # TODO we can't use **kwargs b/c init_in_parent needs the initializer list - @init_in_parent + # TODO we can't use **kwargs b/c the init hook needs an initializer list def __init__(self, voltage_limits: RangeLike = RangeExpr.ALL, signal_limits: RangeLike = RangeExpr.ALL, current_draw: RangeLike = RangeExpr.ZERO, impedance: RangeLike = RangeExpr.INF): diff --git a/edg/electronics_model/VoltagePorts.py b/edg/electronics_model/VoltagePorts.py index 175c197dc..39906cb40 100644 --- a/edg/electronics_model/VoltagePorts.py +++ b/edg/electronics_model/VoltagePorts.py @@ -140,7 +140,6 @@ def __init__(self, voltage_limits: RangeLike = RangeExpr.ALL, class VoltageSinkAdapterGroundReference(CircuitPortAdapter['GroundReference']): - @init_in_parent def __init__(self, current_draw: RangeLike): super().__init__() from .GroundPort import GroundReference @@ -154,7 +153,6 @@ def __init__(self, current_draw: RangeLike): class VoltageSinkAdapterDigitalSource(CircuitPortAdapter['DigitalSource']): - @init_in_parent def __init__(self): from .DigitalPorts import DigitalSource super().__init__() @@ -170,7 +168,6 @@ def __init__(self): class VoltageSinkAdapterAnalogSource(CircuitPortAdapter['AnalogSource']): - @init_in_parent def __init__(self): from .AnalogPort import AnalogSource diff --git a/edg/electronics_model/test_i2c_link.py b/edg/electronics_model/test_i2c_link.py index a09ca6ee9..25f267fdd 100644 --- a/edg/electronics_model/test_i2c_link.py +++ b/edg/electronics_model/test_i2c_link.py @@ -16,7 +16,6 @@ def __init__(self): class I2cTargetBlock(Block): - @init_in_parent def __init__(self, address: IntLike): super().__init__() self.port = self.Port(I2cTarget(DigitalBidir(), [address])) diff --git a/edg/jlcparts/JlcPartsMlcc.py b/edg/jlcparts/JlcPartsMlcc.py index 267293d38..83ea64f98 100644 --- a/edg/jlcparts/JlcPartsMlcc.py +++ b/edg/jlcparts/JlcPartsMlcc.py @@ -7,7 +7,6 @@ class JlcPartsMlcc(PartsTableSelectorFootprint, JlcPartsBase, TableDeratingCapacitor, CeramicCapacitor): _JLC_PARTS_FILE_NAMES = ["CapacitorsMultilayer_Ceramic_Capacitors_MLCC___SMDakaSMT"] - @init_in_parent def __init__(self, *args, capacitance_minimum_size: BoolLike = True, **kwargs): super().__init__(*args, **kwargs) self.capacitance_minimum_size = self.ArgParameter(capacitance_minimum_size) diff --git a/edg/parts/AdcSpi_Mcp3561.py b/edg/parts/AdcSpi_Mcp3561.py index 18eacc538..c477a4e0e 100644 --- a/edg/parts/AdcSpi_Mcp3561.py +++ b/edg/parts/AdcSpi_Mcp3561.py @@ -4,7 +4,6 @@ class Mcp3561_Device(InternalSubcircuit, GeneratorBlock, FootprintBlock): - @init_in_parent def __init__(self, has_ext_ref: BoolLike) -> None: super().__init__() self.avdd = self.Port(VoltageSink( diff --git a/edg/parts/Batteries.py b/edg/parts/Batteries.py index e195be9f4..eb44d2be8 100644 --- a/edg/parts/Batteries.py +++ b/edg/parts/Batteries.py @@ -29,7 +29,6 @@ def contents(self): class Li18650(Battery, FootprintBlock): - @init_in_parent def __init__(self, voltage: RangeLike = (2.5, 4.2)*Volt, *args, actual_voltage: RangeLike = (2.5, 4.2)*Volt, **kwargs): super().__init__(voltage, *args, **kwargs) @@ -56,7 +55,6 @@ def contents(self): class AaBattery(Battery, FootprintBlock): """AA battery holder supporting alkaline and rechargeable chemistries.""" - @init_in_parent def __init__(self, voltage: RangeLike = (1.0, 1.6)*Volt, *args, actual_voltage: RangeLike = (1.0, 1.6)*Volt, **kwargs): super().__init__(voltage, *args, **kwargs) @@ -83,7 +81,6 @@ def contents(self): class AaBatteryStack(Battery, GeneratorBlock): """AA Alkaline battery stack that generates batteries in series""" - @init_in_parent def __init__(self, count: IntLike = 1, *, cell_actual_voltage: RangeLike = (1.0, 1.6)*Volt): super().__init__(voltage=Range.all()) # no voltage spec passed in self.count = self.ArgParameter(count) diff --git a/edg/parts/BatteryCharger_Mcp73831.py b/edg/parts/BatteryCharger_Mcp73831.py index bf736414f..c32c294a5 100644 --- a/edg/parts/BatteryCharger_Mcp73831.py +++ b/edg/parts/BatteryCharger_Mcp73831.py @@ -3,7 +3,6 @@ class Mcp73831_Device(InternalSubcircuit, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, actual_charging_current: RangeLike) -> None: super().__init__() @@ -45,7 +44,6 @@ def contents(self) -> None: class Mcp73831(PowerConditioner, Block): """Single-cell Li-ion / Li-poly charger, seemingly popular on Adafruit and Sparkfun boards.""" - @init_in_parent def __init__(self, charging_current: RangeLike) -> None: super().__init__() diff --git a/edg/parts/BatteryProtector_S8261A.py b/edg/parts/BatteryProtector_S8261A.py index 974f74c0b..2771a2dd7 100644 --- a/edg/parts/BatteryProtector_S8261A.py +++ b/edg/parts/BatteryProtector_S8261A.py @@ -39,7 +39,6 @@ def contents(self) -> None: class S8261A(PowerConditioner, Block): """1-cell LiIon/LiPo Battery protection IC protecting against overcharge, overdischarge, over current. """ - @init_in_parent def __init__(self) -> None: super().__init__() diff --git a/edg/parts/Bldc_Drv8313.py b/edg/parts/Bldc_Drv8313.py index 48d560a64..b4fe7f85c 100644 --- a/edg/parts/Bldc_Drv8313.py +++ b/edg/parts/Bldc_Drv8313.py @@ -102,7 +102,6 @@ def contents(self) -> None: class Drv8313(BldcDriver, GeneratorBlock): - @init_in_parent def __init__(self, *, risense_res: RangeLike = 100*mOhm(tol=0.05)) -> None: super().__init__() self.ic = self.Block(Drv8313_Device()) diff --git a/edg/parts/BoostConverter_AnalogDevices.py b/edg/parts/BoostConverter_AnalogDevices.py index 869d4ab23..65add58b0 100644 --- a/edg/parts/BoostConverter_AnalogDevices.py +++ b/edg/parts/BoostConverter_AnalogDevices.py @@ -3,7 +3,6 @@ class Ltc3429_Device(InternalSubcircuit, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() self.vin = self.Port(VoltageSink( diff --git a/edg/parts/BoostConverter_DiodesInc.py b/edg/parts/BoostConverter_DiodesInc.py index c381f6074..d85b270cb 100644 --- a/edg/parts/BoostConverter_DiodesInc.py +++ b/edg/parts/BoostConverter_DiodesInc.py @@ -3,7 +3,6 @@ class Ap3012_Device(InternalSubcircuit, JlcPart, FootprintBlock): - @init_in_parent def __init__(self): super().__init__() self.pwr_in = self.Port(VoltageSink( diff --git a/edg/parts/BoostConverter_TexasInstruments.py b/edg/parts/BoostConverter_TexasInstruments.py index b18d87dfd..1b4c8f274 100644 --- a/edg/parts/BoostConverter_TexasInstruments.py +++ b/edg/parts/BoostConverter_TexasInstruments.py @@ -3,7 +3,6 @@ class Tps61040_Device(InternalSubcircuit, JlcPart, FootprintBlock): - @init_in_parent def __init__(self): super().__init__() vfb = Range(1.208, 1.258) @@ -159,7 +158,6 @@ def contents(self): class Lm2733_Device(InternalSubcircuit, JlcPart, FootprintBlock): - @init_in_parent def __init__(self): super().__init__() self.pwr_in = self.Port(VoltageSink( diff --git a/edg/parts/BoostConverter_Torex.py b/edg/parts/BoostConverter_Torex.py index f623e7cc8..1e0a4d8f8 100644 --- a/edg/parts/BoostConverter_Torex.py +++ b/edg/parts/BoostConverter_Torex.py @@ -17,7 +17,6 @@ class Xc9142_Device(InternalSubcircuit, FootprintBlock, GeneratorBlock): ('MR-G', 'Package_TO_SOT_SMD:SOT-23-5'), ] - @init_in_parent def __init__(self, output_voltage: RangeLike, frequency: RangeLike = Range.all()): super().__init__() diff --git a/edg/parts/BootstrapVoltageAdder.py b/edg/parts/BootstrapVoltageAdder.py index 120b2fa95..7cfe9f412 100644 --- a/edg/parts/BootstrapVoltageAdder.py +++ b/edg/parts/BootstrapVoltageAdder.py @@ -4,8 +4,7 @@ class BootstrapVoltageAdder(KiCadSchematicBlock, PowerConditioner, Block): """Bipolar (positive and negative) voltage adder using a switched cap circuit. """ - @init_in_parent - def __init__(self, frequency: RangeExpr = 250*kHertz(tol=0), ripple_limit: FloatExpr = 25*mVolt): + def __init__(self, frequency: RangeLike = 250*kHertz(tol=0), ripple_limit: FloatLike = 25*mVolt): super().__init__() self.gnd = self.Port(Ground.empty()) diff --git a/edg/parts/BuckBoostConverter_Custom.py b/edg/parts/BuckBoostConverter_Custom.py index 09c8cddaa..a4548b502 100644 --- a/edg/parts/BuckBoostConverter_Custom.py +++ b/edg/parts/BuckBoostConverter_Custom.py @@ -5,7 +5,6 @@ # and inputs in the center class VoltageSinkConnector(DummyDevice, NetBlock): """Connects two voltage sinks together (FET top sink to exterior source).""" - @init_in_parent def __init__(self, voltage_out: RangeLike, a_current_limits: RangeLike, b_current_limits: RangeLike) -> None: super().__init__() self.a = self.Port(VoltageSource( @@ -20,7 +19,6 @@ def __init__(self, voltage_out: RangeLike, a_current_limits: RangeLike, b_curren class VoltageSourceConnector(DummyDevice, NetBlock): """Connects two voltage sources together (inductor output to FET center 'source').""" - @init_in_parent def __init__(self, a_current_draw: RangeLike, b_current_draw: RangeLike) -> None: super().__init__() self.a = self.Port(VoltageSink( @@ -35,7 +33,6 @@ class CustomSyncBuckBoostConverterPwm(DiscreteBoostConverter, Resettable): """Custom synchronous buck-boost with four PWMs for the switches. Because of the MOSFET body diode, will probably be fine-ish if the buck low-side FET and the boost high-side FET are not driven""" - @init_in_parent def __init__(self, *args, frequency: RangeLike = (100, 1000)*kHertz, ripple_ratio: RangeLike = (0.2, 0.5), diff --git a/edg/parts/BuckConverter_Ap3418.py b/edg/parts/BuckConverter_Ap3418.py index 75eb46f2c..03e8eabca 100644 --- a/edg/parts/BuckConverter_Ap3418.py +++ b/edg/parts/BuckConverter_Ap3418.py @@ -3,7 +3,6 @@ class Ap3418_Device(InternalSubcircuit, FootprintBlock, JlcPart): - @init_in_parent def __init__(self): super().__init__() self.sw = self.Port(VoltageSource()) # internal switch specs not defined, only bulk current limit defined diff --git a/edg/parts/BuckConverter_Custom.py b/edg/parts/BuckConverter_Custom.py index a85b9c1a0..5bc333c8d 100644 --- a/edg/parts/BuckConverter_Custom.py +++ b/edg/parts/BuckConverter_Custom.py @@ -4,7 +4,6 @@ class CustomSyncBuckConverterIndependent(DiscreteBoostConverter): """Custom synchronous buck with two PWM inputs for the high and low side gate drivers. Because of the MOSFET body diode, will probably be fine-ish if the low side FET is not driven.""" - @init_in_parent def __init__(self, *args, frequency: RangeLike = (100, 1000)*kHertz, ripple_ratio: RangeLike = (0.2, 0.5), diff --git a/edg/parts/BuckConverter_Mps.py b/edg/parts/BuckConverter_Mps.py index 2ba747238..f0a2d4034 100644 --- a/edg/parts/BuckConverter_Mps.py +++ b/edg/parts/BuckConverter_Mps.py @@ -5,7 +5,6 @@ class Mp2722_Device(InternalSubcircuit, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, charging_current: RangeLike): super().__init__() self.gnd = self.Port(Ground(), [Common]) @@ -102,7 +101,6 @@ class Mp2722(DiscreteBuckConverter): VSYS_MIN_DEFAULT = 3.588 # regulation target, tracks above this - @init_in_parent def __init__(self, *args: Any, frequency: RangeLike = (900, 1280)*kHertz, charging_current: RangeLike = (0, 3)*Amp, **kwargs: Any): super().__init__(*args, **kwargs) diff --git a/edg/parts/BuckConverter_TexasInstruments.py b/edg/parts/BuckConverter_TexasInstruments.py index 22f6d935e..50de095c9 100644 --- a/edg/parts/BuckConverter_TexasInstruments.py +++ b/edg/parts/BuckConverter_TexasInstruments.py @@ -3,7 +3,6 @@ class Tps561201_Device(InternalSubcircuit, JlcPart, FootprintBlock): - @init_in_parent def __init__(self): super().__init__() self.sw = self.Port(VoltageSource()) # internal switch specs not defined, only bulk current limit defined @@ -84,7 +83,6 @@ def contents(self): class Tps54202h_Device(InternalSubcircuit, JlcPart, FootprintBlock): - @init_in_parent def __init__(self): super().__init__() self.sw = self.Port(VoltageSource( diff --git a/edg/parts/Comparator_Lmv331.py b/edg/parts/Comparator_Lmv331.py index 117919c17..4cb215824 100644 --- a/edg/parts/Comparator_Lmv331.py +++ b/edg/parts/Comparator_Lmv331.py @@ -3,7 +3,6 @@ class Lmv331_Device(InternalSubcircuit, FootprintBlock, JlcPart): - @init_in_parent def __init__(self) -> None: super().__init__() self.gnd = self.Port(Ground()) diff --git a/edg/parts/Connectors.py b/edg/parts/Connectors.py index f8ee50226..58550795d 100644 --- a/edg/parts/Connectors.py +++ b/edg/parts/Connectors.py @@ -5,7 +5,6 @@ @abstract_block class PowerBarrelJack(Connector, PowerSource, Block): """Barrel jack that models a configurable voltage / max current power supply.""" - @init_in_parent def __init__(self, voltage_out: RangeLike = RangeExpr(), current_limits: RangeLike = RangeExpr.ALL) -> None: @@ -60,7 +59,6 @@ class LipoConnector(Connector, Battery): Default pinning has ground being pin 1, and power being pin 2. Connector type not specified, up to the user through a refinement.""" - @init_in_parent def __init__(self, voltage: RangeLike = (2.5, 4.2)*Volt, *args, actual_voltage: RangeLike = (2.5, 4.2)*Volt, **kwargs): from ..electronics_model.PassivePort import PassiveAdapterVoltageSink diff --git a/edg/parts/CurrentSense_Ad8418.py b/edg/parts/CurrentSense_Ad8418.py index 0698f0eee..287748425 100644 --- a/edg/parts/CurrentSense_Ad8418.py +++ b/edg/parts/CurrentSense_Ad8418.py @@ -6,7 +6,6 @@ class Ad8418a_Device(JlcPart, FootprintBlock, InternalSubcircuit): GAIN = Range.from_tolerance(20, 0.0015) - @init_in_parent def __init__(self, in_diff_range: RangeLike): super().__init__() self.gnd = self.Port(Ground(), [Common]) @@ -64,7 +63,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: 'V+': self.pwr, 'V-': self.gnd } - @init_in_parent def __init__(self, in_diff_range: RangeLike): super().__init__() self.in_diff_range = self.ArgParameter(in_diff_range) diff --git a/edg/parts/DacI2c_Mcp4728.py b/edg/parts/DacI2c_Mcp4728.py index 32c409882..b21b68722 100644 --- a/edg/parts/DacI2c_Mcp4728.py +++ b/edg/parts/DacI2c_Mcp4728.py @@ -3,7 +3,6 @@ class Mcp4728_Device(InternalSubcircuit, FootprintBlock, GeneratorBlock, JlcPart): - @init_in_parent def __init__(self) -> None: super().__init__() self.vss = self.Port(Ground()) @@ -66,7 +65,6 @@ class Mcp4728(DigitalToAnalog, GeneratorBlock): Note, MCP47F seems to be a similar architecture but the example application has an optional 0.1uF capacitor on the VoutN lines to reduce noise, which is generated by default here. """ - @init_in_parent def __init__(self, output_caps: BoolLike = True) -> None: super().__init__() self.ic = self.Block(Mcp4728_Device()) diff --git a/edg/parts/DacI2c_Mcp47f.py b/edg/parts/DacI2c_Mcp47f.py index e43a90483..0aa8429c4 100644 --- a/edg/parts/DacI2c_Mcp47f.py +++ b/edg/parts/DacI2c_Mcp47f.py @@ -2,7 +2,6 @@ class Mcp47f_Device(InternalSubcircuit, FootprintBlock, GeneratorBlock): - @init_in_parent def __init__(self, addr_lsb: IntLike) -> None: super().__init__() self.vss = self.Port(Ground()) diff --git a/edg/parts/Distance_Vl53l0x.py b/edg/parts/Distance_Vl53l0x.py index bcec5706a..d23df7135 100644 --- a/edg/parts/Distance_Vl53l0x.py +++ b/edg/parts/Distance_Vl53l0x.py @@ -106,7 +106,6 @@ def generate(self): class Vl53l0xArray(DistanceSensor, GeneratorBlock): """Array of Vl53l0x with common I2C but individually exposed XSHUT pins and optionally GPIO1 (interrupt).""" - @init_in_parent def __init__(self, count: IntLike, *, first_reset_fixed: BoolLike = False): super().__init__() self.pwr = self.Port(VoltageSink.empty(), [Power]) diff --git a/edg/parts/EInkBoostPowerPath.py b/edg/parts/EInkBoostPowerPath.py index f7b9b0287..d0b52b356 100644 --- a/edg/parts/EInkBoostPowerPath.py +++ b/edg/parts/EInkBoostPowerPath.py @@ -5,7 +5,6 @@ class EInkBoostPowerPath(Interface, KiCadSchematicBlock): """Boost converter power path for e-ink displays with negative voltage generation through a bootstrap switched-cap circuit. Current is the peak current through the FET and diodes.""" - @init_in_parent def __init__(self, voltage_out: RangeLike, current: RangeLike, inductance: RangeLike, in_capacitance: RangeLike, out_capacitance: RangeLike, resistance: RangeLike, diode_voltage_drop: RangeLike = (0, 0.5)*Volt): diff --git a/edg/parts/EInk_Er_Epd027_2.py b/edg/parts/EInk_Er_Epd027_2.py index 7f082abd5..916e9d634 100644 --- a/edg/parts/EInk_Er_Epd027_2.py +++ b/edg/parts/EInk_Er_Epd027_2.py @@ -82,7 +82,6 @@ class Er_Epd027_2(EInk, GeneratorBlock): (Probably) compatible with https://www.waveshare.com/w/upload/b/ba/2.7inch_e-Paper_V2_Specification.pdf, and https://www.waveshare.com/w/upload/7/7b/2.7inch-e-paper-b-v2-specification.pdf """ - @init_in_parent def __init__(self) -> None: super().__init__() self.device = self.Block(Er_Epd027_2_Device()) diff --git a/edg/parts/EInk_WaveshareDriver.py b/edg/parts/EInk_WaveshareDriver.py index 396d093df..436056bd9 100644 --- a/edg/parts/EInk_WaveshareDriver.py +++ b/edg/parts/EInk_WaveshareDriver.py @@ -78,7 +78,6 @@ class Waveshare_Epd(EInk, GeneratorBlock): https://www.waveshare.com/wiki/E-Paper_Driver_HAT excluding the "clever" reset circuit """ - @init_in_parent def __init__(self) -> None: super().__init__() self.device = self.Block(Waveshare_Epd_Device()) diff --git a/edg/parts/EnvironmentalSensor_Ti.py b/edg/parts/EnvironmentalSensor_Ti.py index d2ba3f2e9..ac0160e64 100644 --- a/edg/parts/EnvironmentalSensor_Ti.py +++ b/edg/parts/EnvironmentalSensor_Ti.py @@ -52,7 +52,6 @@ def contents(self): class Tmp1075n_Device(InternalSubcircuit, FootprintBlock, JlcPart, GeneratorBlock): - @init_in_parent def __init__(self, addr_lsb: IntLike) -> None: super().__init__() self.gnd = self.Port(Ground()) @@ -97,7 +96,6 @@ def generate(self) -> None: class Tmp1075n(TemperatureSensor, Block): """Temperature sensor with 0.25C typical accuracy""" - @init_in_parent def __init__(self, addr_lsb: IntLike = 0): super().__init__() self.ic = self.Block(Tmp1075n_Device(addr_lsb)) diff --git a/edg/parts/Ina219.py b/edg/parts/Ina219.py index 207c41f42..43473e960 100644 --- a/edg/parts/Ina219.py +++ b/edg/parts/Ina219.py @@ -3,7 +3,6 @@ class Ina219_Device(InternalSubcircuit, JlcPart, FootprintBlock, Block): - @init_in_parent def __init__(self): super().__init__() @@ -52,7 +51,6 @@ def contents(self): class Ina219(CurrentSensor, Block): """Current/voltage/power monitor with I2C interface""" - @init_in_parent def __init__(self, shunt_resistor: RangeLike = 2.0 * mOhm(tol=0.05)): super().__init__() self.ic = self.Block(Ina219_Device()) diff --git a/edg/parts/IoExpander_Pca9554.py b/edg/parts/IoExpander_Pca9554.py index 4de5d3bcd..3a6414f88 100644 --- a/edg/parts/IoExpander_Pca9554.py +++ b/edg/parts/IoExpander_Pca9554.py @@ -6,7 +6,6 @@ class Pca9554_Device(PinMappable, InternalSubcircuit, FootprintBlock, JlcPart, GeneratorBlock): - @init_in_parent def __init__(self, addr_lsb: IntLike, **kwags) -> None: super().__init__(**kwags) self.gnd = self.Port(Ground()) @@ -80,7 +79,6 @@ def generate(self) -> None: class Pca9554(IoExpander, PinMappable): """8 bit I2C IO expander""" - @init_in_parent def __init__(self, addr_lsb: IntLike = 0) -> None: super().__init__() self.ic = self.Block(Pca9554_Device(addr_lsb=addr_lsb, pin_assigns=self.pin_assigns)) diff --git a/edg/parts/IoExpander_Pcf8574.py b/edg/parts/IoExpander_Pcf8574.py index 7d2ed6bc7..a75a0c9d5 100644 --- a/edg/parts/IoExpander_Pcf8574.py +++ b/edg/parts/IoExpander_Pcf8574.py @@ -6,7 +6,6 @@ class Pcf8574_Device(PinMappable, InternalSubcircuit, FootprintBlock, JlcPart, GeneratorBlock): - @init_in_parent def __init__(self, addr_lsb: IntLike, **kwags) -> None: super().__init__(**kwags) self.gnd = self.Port(Ground()) @@ -80,7 +79,6 @@ def generate(self) -> None: class Pcf8574(IoExpander, PinMappable): """8 bit I2C IO expander with 'quasi-bidirectional IOs'""" - @init_in_parent def __init__(self, addr_lsb: IntLike = 0) -> None: super().__init__() self.ic = self.Block(Pcf8574_Device(addr_lsb=addr_lsb, pin_assigns=self.pin_assigns)) diff --git a/edg/parts/Jacdac.py b/edg/parts/Jacdac.py index b3e2dc230..d52f061b5 100644 --- a/edg/parts/Jacdac.py +++ b/edg/parts/Jacdac.py @@ -53,7 +53,6 @@ class JacdacEdgeConnectorBare(JacdacSubcircuit, FootprintBlock, GeneratorBlock): If the power sink (power is sunk into the port and off-board) is connected, is_power_provider indicates whether this port should model the maximum downstream current draw """ - @init_in_parent def __init__(self, is_power_provider: BoolLike = False) -> None: super().__init__() self.is_power_provider = self.ArgParameter(is_power_provider) @@ -134,7 +133,6 @@ class JacdacEdgeConnector(Connector, JacdacSubcircuit, GeneratorBlock): Requires this KiCad footprint library to be available: https://github.com/mattoppenheim/jacdac """ - @init_in_parent def __init__(self, is_power_provider: BoolLike = False) -> None: super().__init__() self.is_power_provider = self.ArgParameter(is_power_provider) diff --git a/edg/parts/JlcBlackbox.py b/edg/parts/JlcBlackbox.py index 33796a772..c0759da68 100644 --- a/edg/parts/JlcBlackbox.py +++ b/edg/parts/JlcBlackbox.py @@ -22,7 +22,6 @@ def block_pinning(block: KiCadJlcBlackbox) -> Mapping[str, BasePort]: return {pin: block.ports.request(pin) for pin in pin_numbers} return block_model, block_pinning - @init_in_parent def __init__(self, kicad_pins: ArrayStringLike, kicad_refdes_prefix: StringLike, kicad_footprint: StringLike, kicad_part: StringLike, kicad_value: StringLike, kicad_datasheet: StringLike, kicad_jlcpcb_part: StringLike): diff --git a/edg/parts/JlcCapacitor.py b/edg/parts/JlcCapacitor.py index d01687648..83b35fea8 100644 --- a/edg/parts/JlcCapacitor.py +++ b/edg/parts/JlcCapacitor.py @@ -32,7 +32,6 @@ class JlcCapacitor(JlcTableSelector, PartsTableSelectorFootprint, TableDeratingC 'Capacitor_SMD:C_1812_4532Metric': 0.04, # arbitrary, copy from 1206 } - @init_in_parent def __init__(self, *args, capacitance_minimum_size: BoolLike = True, **kwargs): super().__init__(*args, **kwargs) self.capacitance_minimum_size = self.ArgParameter(capacitance_minimum_size) @@ -131,7 +130,6 @@ def _make_parallel_footprints(self, row: PartsTableRow) -> None: class JlcDummyCapacitor(JlcPart, DummyCapacitorFootprint): """Dummy capacitor that additionally has JLC part fields """ - @init_in_parent def __init__(self, set_lcsc_part: StringLike = "", set_basic_part: BoolLike = False, footprint: StringLike = "", manufacturer: StringLike = "", part_number: StringLike = "", value: StringLike = "", *args, **kwargs) -> None: diff --git a/edg/parts/JlcElectrolyticCapacitor.py b/edg/parts/JlcElectrolyticCapacitor.py index 66ff62385..17b08c810 100644 --- a/edg/parts/JlcElectrolyticCapacitor.py +++ b/edg/parts/JlcElectrolyticCapacitor.py @@ -19,7 +19,6 @@ class JlcAluminumCapacitor(PartsTableSelectorFootprint, JlcTableSelector, TableC }), ] - @init_in_parent def __init__(self, *args, capacitance_minimum_size: BoolLike = True, **kwargs): super().__init__(*args, **kwargs) self.capacitance_minimum_size = self.ArgParameter(capacitance_minimum_size) diff --git a/edg/parts/JlcFet.py b/edg/parts/JlcFet.py index bf94c9273..5e9baebaa 100644 --- a/edg/parts/JlcFet.py +++ b/edg/parts/JlcFet.py @@ -10,7 +10,6 @@ class FetFallbackGateCharge(PartsTableSelector, BaseTableFet): """A TableFet that allows a fallback gate charge if not specified in the table. Unspecified entries must be Range.all(), which will be substituted with the fallback value in per-Block post-processing.""" - @init_in_parent def __init__(self, *args, fallback_gate_charge: RangeLike = Range.from_tolerance(3000e-9, 0), **kwargs): super().__init__(*args, **kwargs) # allow the user to specify a gate charge diff --git a/edg/parts/JlcOscillator.py b/edg/parts/JlcOscillator.py index b60a0ac65..2c8956242 100644 --- a/edg/parts/JlcOscillator.py +++ b/edg/parts/JlcOscillator.py @@ -9,7 +9,6 @@ class JlcOscillator_Device(InternalSubcircuit, Block): Defines a standard interface, and specifies the footprint here.""" FOOTPRINT: str - @init_in_parent def __init__(self, in_kicad_part: StringLike, in_kicad_value: StringLike, in_kicad_datasheet: StringLike, in_lcsc_part: StringLike, in_actual_basic_part: BoolLike): super().__init__() @@ -29,7 +28,6 @@ def __init__(self, in_kicad_part: StringLike, in_kicad_value: StringLike, in_kic class Sg8101_Base_Device(JlcOscillator_Device, JlcPart, FootprintBlock): FOOTPRINT: str - @init_in_parent def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.gnd.init_from(Ground()) diff --git a/edg/parts/JlcPart.py b/edg/parts/JlcPart.py index 6a818dd68..879fdfc2c 100644 --- a/edg/parts/JlcPart.py +++ b/edg/parts/JlcPart.py @@ -9,7 +9,6 @@ class JlcPart(Block): """Provides additional data fields for JLCPCB parts for their SMT service. By default, this does not check for basic parts, but that can be changed in refinements. """ - @init_in_parent def __init__(self, *args, require_basic_part: BoolLike = False, **kwargs): super().__init__(*args, **kwargs) self.lcsc_part = self.Parameter(StringExpr()) diff --git a/edg/parts/LedDriver_Al8861.py b/edg/parts/LedDriver_Al8861.py index eaf271d47..8a3e5af59 100644 --- a/edg/parts/LedDriver_Al8861.py +++ b/edg/parts/LedDriver_Al8861.py @@ -3,7 +3,6 @@ class Al8861_Device(InternalSubcircuit, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, peak_output_current: FloatLike): super().__init__() @@ -46,7 +45,6 @@ def contents(self): class Al8861(LedDriverPwm, LedDriverSwitchingConverter, LedDriver, GeneratorBlock): """AL8861 buck LED driver.""" - @init_in_parent def __init__(self, diode_voltage_drop: RangeLike = Range.all()): super().__init__() diff --git a/edg/parts/LedDriver_Tps92200.py b/edg/parts/LedDriver_Tps92200.py index a2f36898a..f5001977e 100644 --- a/edg/parts/LedDriver_Tps92200.py +++ b/edg/parts/LedDriver_Tps92200.py @@ -3,7 +3,6 @@ class Tps92200_Device(InternalSubcircuit, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, peak_output_current: FloatLike): super().__init__() @@ -47,7 +46,6 @@ def contents(self): class Tps92200(LedDriverPwm, LedDriver, GeneratorBlock): """TPS92200 buck 4-30V 1.5A 1 MHz LED driver and 150nS min on-time. This is the -D2 variant, with PWM input for 1-100% range as a 20-200kHz digital signal""" - @init_in_parent def __init__(self, led_voltage: RangeLike = (1, 4)*Volt, *, input_ripple_limit: FloatLike = 0.2*Volt, # from 8.2 example application output_ripple_limit: FloatLike = 0.01*Volt) -> None: diff --git a/edg/parts/LedMatrix.py b/edg/parts/LedMatrix.py index 33b4cd22f..0dfef3173 100644 --- a/edg/parts/LedMatrix.py +++ b/edg/parts/LedMatrix.py @@ -164,7 +164,6 @@ def _svgpcb_bbox(self) -> Tuple[float, float, float, float]: return (-1.0, -1.0, self._svgpcb_get(self.ncols) * .2 * 25.4 + 1.0, (self._svgpcb_get(self.nrows) + 1) * .2 * 25.4 + 1.0) - @init_in_parent def __init__(self, nrows: IntLike, ncols: IntLike, color: LedColorLike = Led.Any, current_draw: RangeLike = (1, 10)*mAmp): super().__init__() diff --git a/edg/parts/LinearRegulators.py b/edg/parts/LinearRegulators.py index 1e88435c2..3a96282c5 100644 --- a/edg/parts/LinearRegulators.py +++ b/edg/parts/LinearRegulators.py @@ -5,7 +5,6 @@ class Ld1117_Device(InternalSubcircuit, LinearRegulatorDevice, GeneratorBlock, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() @@ -60,7 +59,6 @@ def contents(self) -> None: class Ldl1117_Device(InternalSubcircuit, LinearRegulatorDevice, GeneratorBlock, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() @@ -121,7 +119,6 @@ def contents(self) -> None: class Ap2204k_Device(InternalSubcircuit, LinearRegulatorDevice, GeneratorBlock, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() @@ -195,7 +192,6 @@ def contents(self): class Ap7215_Device(InternalSubcircuit, LinearRegulatorDevice, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() @@ -235,7 +231,6 @@ def contents(self): class Xc6206p_Device(InternalSubcircuit, LinearRegulatorDevice, GeneratorBlock, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() @@ -306,7 +301,6 @@ def contents(self) -> None: class Xc6209_Device(InternalSubcircuit, LinearRegulatorDevice, GeneratorBlock, JlcPart, FootprintBlock): # Also pin-compatible with MCP1802 and NJM2882F (which has a noise bypass pin) - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() @@ -376,7 +370,6 @@ def contents(self) -> None: class Ap2210_Device(InternalSubcircuit, LinearRegulatorDevice, GeneratorBlock, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() @@ -448,7 +441,6 @@ def contents(self) -> None: class Lp5907_Device(InternalSubcircuit, LinearRegulatorDevice, SelectorFootprint, PartsTablePart, JlcPart, GeneratorBlock, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() @@ -552,7 +544,6 @@ def contents(self) -> None: class Tlv757p_Device(InternalSubcircuit, LinearRegulatorDevice, PartsTablePart, JlcPart, GeneratorBlock, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() @@ -633,7 +624,6 @@ def contents(self) -> None: class L78l_Device(InternalSubcircuit, LinearRegulatorDevice, JlcPart, GeneratorBlock, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() diff --git a/edg/parts/Logic_74Ahct.py b/edg/parts/Logic_74Ahct.py index 73946310a..1ee82eb5f 100644 --- a/edg/parts/Logic_74Ahct.py +++ b/edg/parts/Logic_74Ahct.py @@ -3,7 +3,6 @@ class L74Ahct1g125_Device(InternalSubcircuit, FootprintBlock, JlcPart): - @init_in_parent def __init__(self) -> None: super().__init__() self.gnd = self.Port(Ground()) @@ -41,7 +40,6 @@ def contents(self) -> None: class L74Ahct1g125(Interface, Block): """Single buffer, useful as a level shifter""" - @init_in_parent def __init__(self) -> None: super().__init__() self.ic = self.Block(L74Ahct1g125_Device()) diff --git a/edg/parts/Logic_74Lvc.py b/edg/parts/Logic_74Lvc.py index e1bdec527..024e8cb12 100644 --- a/edg/parts/Logic_74Lvc.py +++ b/edg/parts/Logic_74Lvc.py @@ -3,7 +3,6 @@ class Sn74lvc1g74_Device(InternalSubcircuit, FootprintBlock, JlcPart): - @init_in_parent def __init__(self) -> None: super().__init__() self.gnd = self.Port(Ground()) @@ -56,7 +55,6 @@ class Sn74lvc1g74(Interface, Block): """D flip-flop with clear and preset TODO: should extend an abstract flip-lop interface, with async (n)set and (n)clear mixins""" - @init_in_parent def __init__(self) -> None: super().__init__() self.ic = self.Block(Sn74lvc1g74_Device()) diff --git a/edg/parts/Microcontroller_Esp.py b/edg/parts/Microcontroller_Esp.py index d0fc35089..1a679f5ca 100644 --- a/edg/parts/Microcontroller_Esp.py +++ b/edg/parts/Microcontroller_Esp.py @@ -22,7 +22,6 @@ class EspProgrammingAutoReset(BlockInterfaceMixin[EspProgrammingHeader]): """Mixin for ESP programming header with auto-reset and auto-boot pins. By default, these are required to be connected (since it doesn't make sense to instantiate this without connecting the additional pins to the micro), but can be disabled with parameters.""" - @init_in_parent def __init__(self, *args, require_auto_reset: BoolLike = True, **kwargs) -> None: super().__init__(*args, **kwargs) @@ -79,7 +78,6 @@ def contents(self) -> None: class HasEspProgramming(IoController, GeneratorBlock): """A mixin for a block (typically an IoController wrapper) that has an ESP style programming header. Can generate into the standard UART cable, the auto-programming header, or TODO a boundary port.""" - @init_in_parent def __init__(self, programming: StringLike = "uart-button"): super().__init__() self.programming = self.ArgParameter(programming) # programming connector to generate diff --git a/edg/parts/Microcontroller_Stm32f103.py b/edg/parts/Microcontroller_Stm32f103.py index 24874906a..35c31b0ec 100644 --- a/edg/parts/Microcontroller_Stm32f103.py +++ b/edg/parts/Microcontroller_Stm32f103.py @@ -250,7 +250,6 @@ class Stm32f103_48_Device(Stm32f103Base_Device): class UsbDpPullUp(InternalSubcircuit, Block): - @init_in_parent def __init__(self, resistance: RangeLike): super().__init__() self.pwr = self.Port(VoltageSink.empty(), [Power]) diff --git a/edg/parts/Microphone_Sd18ob261.py b/edg/parts/Microphone_Sd18ob261.py index c646208c5..4aacd59eb 100644 --- a/edg/parts/Microphone_Sd18ob261.py +++ b/edg/parts/Microphone_Sd18ob261.py @@ -48,7 +48,6 @@ class Sd18ob261(Microphone, GeneratorBlock): """SD18OB261-060 PDM microphone, probably footprint-compatible with similar Knowles devices. Application circuit is not specified in the datasheet, this uses the one from SPH0655LM4H (single 0.1uF decap).""" - @init_in_parent def __init__(self): super().__init__() diff --git a/edg/parts/MotorDriver_Drv8870.py b/edg/parts/MotorDriver_Drv8870.py index b6602fb6a..a2a305907 100644 --- a/edg/parts/MotorDriver_Drv8870.py +++ b/edg/parts/MotorDriver_Drv8870.py @@ -61,7 +61,6 @@ def contents(self) -> None: class Drv8870(BrushedMotorDriver): """Brushed DC motor driver, 6.5-45v, PWM control, internally current limited using current sense and trip point""" - @init_in_parent def __init__(self, current_trip: RangeLike = (2, 3)*Amp) -> None: super().__init__() self.ic = self.Block(Drv8870_Device()) diff --git a/edg/parts/Neopixel.py b/edg/parts/Neopixel.py index 9dc95e5f8..1c25b9afa 100644 --- a/edg/parts/Neopixel.py +++ b/edg/parts/Neopixel.py @@ -196,7 +196,6 @@ def __init__(self) -> None: class NeopixelArray(Light, GeneratorBlock): """An array of Neopixels""" - @init_in_parent def __init__(self, count: IntLike): super().__init__() self.din = self.Port(DigitalSink.empty(), [Input]) diff --git a/edg/parts/PowerConditioning.py b/edg/parts/PowerConditioning.py index 0b9244ae3..c4fc5a3b1 100644 --- a/edg/parts/PowerConditioning.py +++ b/edg/parts/PowerConditioning.py @@ -29,7 +29,6 @@ class BufferedSupply(PowerConditioner): See https://electronics.stackexchange.com/questions/178605/op-amp-mosfet-constant-current-power-source """ - @init_in_parent def __init__(self, charging_current: RangeLike, sense_resistance: RangeLike, voltage_drop: RangeLike) -> None: super().__init__() @@ -113,7 +112,6 @@ class SingleDiodePowerMerge(PowerConditioner, Block): """Single-diode power merge block for two voltage sources, where the lower voltage one is diode-gated and less preferred if both are connected. """ - @init_in_parent def __init__(self, voltage_drop: RangeLike, reverse_recovery_time: RangeLike = RangeExpr.ALL) -> None: super().__init__() @@ -147,7 +145,6 @@ def __init__(self, voltage_drop: RangeLike, reverse_recovery_time: RangeLike = R class DiodePowerMerge(PowerConditioner, Block): """Diode power merge block for two voltage sources. """ - @init_in_parent def __init__(self, voltage_drop: RangeLike, reverse_recovery_time: RangeLike = (0, float('inf'))) -> None: super().__init__() @@ -195,7 +192,6 @@ class PriorityPowerOr(PowerConditioner, KiCadSchematicBlock, Block): The higher priority input incurs a diode drop, while the lower priority input has a FET. As a side effect, the FET power path also acts as reverse polarity protection. """ - @init_in_parent def __init__(self, diode_voltage_drop: RangeLike, fet_rds_on: RangeLike) -> None: super().__init__() @@ -264,8 +260,6 @@ class PmosReverseProtection(PowerConditioner, KiCadSchematicBlock, Block): 100R-330R is good but 1k-50k can be used for continuous load. Ref: https://components101.com/articles/design-guide-pmos-mosfet-for-reverse-voltage-polarity-protection """ - - @init_in_parent def __init__(self, gate_resistor: RangeLike = 10 * kOhm(tol=0.05), rds_on: RangeLike = (0, 0.1) * Ohm): super().__init__() self.gnd = self.Port(Ground.empty(), [Common]) @@ -307,8 +301,6 @@ class PmosChargerReverseProtection(PowerConditioner, KiCadSchematicBlock, Block) But always reverse protect. R1 and R2 are the pullup bias resistors for mp1 and mp2 PFet. More info at: https://www.edn.com/reverse-voltage-protection-for-battery-chargers/ """ - - @init_in_parent def __init__(self, r1_val: RangeLike = 100 * kOhm(tol=0.01), r2_val: RangeLike = 100 * kOhm(tol=0.01), rds_on: RangeLike = (0, 0.1) * Ohm): super().__init__() @@ -375,8 +367,6 @@ class SoftPowerGate(PowerSwitch, KiCadSchematicBlock, Block): # migrate from th """A high-side PFET power gate that has a button to power on, can be latched on by an external signal, and provides the button output as a signal. """ - - @init_in_parent def __init__(self, pull_resistance: RangeLike = 10 * kOhm(tol=0.05), amp_resistance: RangeLike = 10 * kOhm(tol=0.05), diode_drop: RangeLike = (0, 0.4) * Volt): super().__init__() @@ -455,7 +445,6 @@ def contents(self): class SoftPowerSwitch(PowerSwitch, Block): """A software power switch that adds a power button a user can turn on """ - @init_in_parent def __init__(self, pull_resistance: RangeLike = 10 * kOhm(tol=0.05), amp_resistance: RangeLike = 10 * kOhm(tol=0.05), diode_drop: RangeLike = (0, 0.4) * Volt): super().__init__() diff --git a/edg/parts/ResetGenerator_Apx803s.py b/edg/parts/ResetGenerator_Apx803s.py index 69015a6bd..25d561db1 100644 --- a/edg/parts/ResetGenerator_Apx803s.py +++ b/edg/parts/ResetGenerator_Apx803s.py @@ -3,7 +3,6 @@ class Apx803s_Device(InternalSubcircuit, FootprintBlock, GeneratorBlock, JlcPart): - @init_in_parent def __init__(self, reset_threshold: RangeLike) -> None: super().__init__() self.gnd = self.Port(Ground()) @@ -47,7 +46,6 @@ def generate(self) -> None: class Apx803s(Interface, Block): - @init_in_parent def __init__(self, reset_threshold: RangeLike = (2.88, 2.98)*Volt) -> None: # expanded range for FP precision super().__init__() self.ic = self.Block(Apx803s_Device(reset_threshold)) # datasheet doesn't require decaps diff --git a/edg/parts/ResistiveSensor.py b/edg/parts/ResistiveSensor.py index a40b2d3f0..133850403 100644 --- a/edg/parts/ResistiveSensor.py +++ b/edg/parts/ResistiveSensor.py @@ -6,7 +6,6 @@ class ConnectorResistiveSensor(Analog, Block): that is part of this block) using a simple voltage divider circuit. The external resistor is on the bottom (which makes this of a classic Wheatstone Bridge as drawn on Wikipedia).""" - @init_in_parent def __init__(self, resistance_range: RangeLike, fixed_resistance: RangeLike) -> None: super().__init__() self.resistance_range = self.ArgParameter(resistance_range) diff --git a/edg/parts/Rf_Pn7160.py b/edg/parts/Rf_Pn7160.py index 6f1e2980e..7e4a9a695 100644 --- a/edg/parts/Rf_Pn7160.py +++ b/edg/parts/Rf_Pn7160.py @@ -27,7 +27,6 @@ def impedance_from_lrc(cls, freq: float, inductance: float, resistance: float, c ((1 - (w**2) * inductance * capacitance)**2 + (w * resistance * capacitance)**2) return complex(realpart, imagpart) - @init_in_parent def __init__(self, ant_footprint: StringLike, freq: FloatLike, inductance: FloatLike, resistance: FloatLike, capacitance: FloatLike): super().__init__() @@ -63,7 +62,6 @@ def damp_res_from_impedance(self, impedance: complex, target_q: float) -> float: For differential configuration, halve the result and split among the +/- terminals.""" return impedance.imag / target_q - impedance.real - @init_in_parent def __init__(self, target_q: FloatLike, ant_r: FloatLike, ant_x: FloatLike): super().__init__() self.in1 = self.Port(Passive()) @@ -101,9 +99,8 @@ class DifferentialLcLowpassFilter(GeneratorBlock, RfFilter): def _calculate_capacitance(cls, freq_cutoff: float, inductance: float) -> float: return 1 / (inductance * (2*pi*freq_cutoff)**2) # from f = 1 / (2 pi sqrt(LC)) - @init_in_parent def __init__(self, freq_cutoff: FloatLike, inductance: FloatLike, input_res: FloatLike, - freq: FloatLike, current: RangeExpr, voltage: RangeExpr): + freq: FloatLike, current: RangeLike, voltage: RangeLike): super().__init__() self.freq_cutoff = self.ArgParameter(freq_cutoff) self.inductance = self.ArgParameter(inductance) @@ -154,7 +151,6 @@ def _calculate_se_values(cls, freq: float, z1: complex, z2: complex) -> Tuple[fl se_cp = PiLowPassFilter._reactance_to_capacitance(freq, se_xp) return se_cs, se_cp - @init_in_parent def __init__(self, freq: FloatLike, src_r: FloatLike, src_x: FloatLike, snk_r: FloatLike, snk_x: FloatLike, voltage: RangeLike): super().__init__() @@ -192,7 +188,6 @@ def generate(self): class Pn7160RxFilter(InternalSubcircuit, Block): - @init_in_parent def __init__(self, resistance: RangeLike, capacitance: RangeLike, voltage: RangeLike): super().__init__() self.resistance = self.ArgParameter(resistance) diff --git a/edg/parts/Rf_Sx1262.py b/edg/parts/Rf_Sx1262.py index 7b2c903a5..206e6620d 100644 --- a/edg/parts/Rf_Sx1262.py +++ b/edg/parts/Rf_Sx1262.py @@ -99,7 +99,6 @@ def _calculate_values(cls, freq: float, z_int: complex, z_ext: complex) -> Tuple l_c_new = (l_c * cp) / (cp - l_c) return l_l, l_c_new, cp - @init_in_parent def __init__(self, frequency: FloatLike, src_resistance: FloatLike, src_reactance: FloatLike, load_resistance: FloatLike, tolerance: FloatLike, voltage: RangeLike, current: RangeLike): diff --git a/edg/parts/SpeakerDriver_Analog.py b/edg/parts/SpeakerDriver_Analog.py index 340329ef7..0ffce861f 100644 --- a/edg/parts/SpeakerDriver_Analog.py +++ b/edg/parts/SpeakerDriver_Analog.py @@ -131,7 +131,6 @@ def contents(self): class Tpa2005d1(SpeakerDriver, Block): """TPA2005D1 configured in single-ended input mode. Possible semi-pin-compatible with PAM8302AASCR (C113367), but which has internal resistor.""" - @init_in_parent def __init__(self, gain: RangeLike = Range.from_tolerance(20, 0.2)): super().__init__() # TODO should be a SpeakerDriver abstract part @@ -229,7 +228,6 @@ def contents(self): class Pam8302a(SpeakerDriver, Block): """PAM8302A configured in single-ended input mode.""" - @init_in_parent def __init__(self): super().__init__() diff --git a/edg/parts/SpeakerDriver_Max98357a.py b/edg/parts/SpeakerDriver_Max98357a.py index 29390a2d9..9e6353e1d 100644 --- a/edg/parts/SpeakerDriver_Max98357a.py +++ b/edg/parts/SpeakerDriver_Max98357a.py @@ -75,7 +75,6 @@ def generate(self): class Max98357a(SpeakerDriver, Block): """MAX98357A I2S speaker driver with default gain.""" - @init_in_parent def __init__(self): super().__init__() diff --git a/edg/parts/Speakers.py b/edg/parts/Speakers.py index 951fbbe80..0bb704e57 100644 --- a/edg/parts/Speakers.py +++ b/edg/parts/Speakers.py @@ -12,7 +12,6 @@ def __init__(self): class ConnectorSpeaker(Speaker): """Speaker that delegates to a PassiveConnector and with configurable impedance.""" - @init_in_parent def __init__(self, impedance: RangeLike = 8*Ohm(tol=0)): super().__init__() diff --git a/edg/parts/SpiMemory_93Lc.py b/edg/parts/SpiMemory_93Lc.py index 4e34523be..0b1db327e 100644 --- a/edg/parts/SpiMemory_93Lc.py +++ b/edg/parts/SpiMemory_93Lc.py @@ -19,7 +19,6 @@ class E93Lc_B_Device(InternalSubcircuit, GeneratorBlock, JlcPart, FootprintBlock # 'C616337', False), # BT-I/OT variant ] - @init_in_parent def __init__(self, size: RangeLike): super().__init__() self.vcc = self.Port(VoltageSink( diff --git a/edg/parts/SpiMemory_W25q.py b/edg/parts/SpiMemory_W25q.py index e52d36e11..615ba3d61 100644 --- a/edg/parts/SpiMemory_W25q.py +++ b/edg/parts/SpiMemory_W25q.py @@ -17,7 +17,6 @@ class W25q_Device(InternalSubcircuit, GeneratorBlock, JlcPart, FootprintBlock): # higher capacity variants available but not in SOIC-8 ] - @init_in_parent def __init__(self, size: RangeLike): super().__init__() self.vcc = self.Port(VoltageSink( diff --git a/edg/parts/StepperDriver_A4988.py b/edg/parts/StepperDriver_A4988.py index 0ba7e843a..fe22b0a85 100644 --- a/edg/parts/StepperDriver_A4988.py +++ b/edg/parts/StepperDriver_A4988.py @@ -109,7 +109,6 @@ def contents(self) -> None: class A4988(BrushedMotorDriver, GeneratorBlock): """Bipolar stepper motor driver with microstepping (1:2/4/8/16) and current limiting. 8-35V input, up to 2A.""" - @init_in_parent def __init__(self, step_resolution: IntLike = 16, itrip: RangeLike = 1*Amp(tol=0.15), itrip_vref: RangeLike = 0.25*Volt(tol=0.08)) -> None: @@ -207,7 +206,6 @@ def generate(self) -> None: class PololuA4988(BrushedMotorDriver, WrapperFootprintBlock, GeneratorBlock): """Pololu breakout board for the A4988 stepper driver. Adjustable current limit with onboard trimpot.""" - @init_in_parent def __init__(self, step_resolution: IntLike = 16): super().__init__() self.step_resolution = self.ArgParameter(step_resolution, doc="microstepping resolution (1, 2, 4, 8, or 16)") diff --git a/edg/parts/SwitchMatrix.py b/edg/parts/SwitchMatrix.py index 168a67874..e4610e099 100644 --- a/edg/parts/SwitchMatrix.py +++ b/edg/parts/SwitchMatrix.py @@ -107,7 +107,6 @@ def _svgpcb_bbox(self) -> Tuple[float, float, float, float]: return (-1.0, -1.0, self._svgpcb_get(self.ncols) * 0.5 * 25.4 + 1.0, (self._svgpcb_get(self.nrows) + 1) * .5 * 25.4 + 1.0) - @init_in_parent def __init__(self, nrows: IntLike, ncols: IntLike, voltage_drop: RangeLike = (0, 0.7)*Volt): super().__init__() diff --git a/edg/parts/SwitchedCap_TexasInstruments.py b/edg/parts/SwitchedCap_TexasInstruments.py index a84cdf214..a01903a9b 100644 --- a/edg/parts/SwitchedCap_TexasInstruments.py +++ b/edg/parts/SwitchedCap_TexasInstruments.py @@ -5,7 +5,6 @@ class Lm2664_Device(InternalSubcircuit, JlcPart, FootprintBlock): FREQUENCY = Range(40000, 80000) # Hz SWITCH_RESISTANCE = Range(4, 8) # Ohm - @init_in_parent def __init__(self): super().__init__() self.gnd = self.Port(Ground(), [Common]) @@ -49,7 +48,6 @@ def contents(self): class Lm2664(PowerConditioner, Block): """Switched capacitor inverter""" - @init_in_parent def __init__(self, output_resistance_limit: FloatLike = 25 * Ohm, output_ripple_limit: FloatLike = 25 * mVolt): super().__init__() diff --git a/edg/parts/TestPoint_Rc.py b/edg/parts/TestPoint_Rc.py index 6b100fcce..faa27a2df 100644 --- a/edg/parts/TestPoint_Rc.py +++ b/edg/parts/TestPoint_Rc.py @@ -9,7 +9,6 @@ class TeRc(TestPoint, FootprintBlock, GeneratorBlock): '1206': ('RCS-0C', 'edg:TestPoint_TE_RCS_RCW_1206'), } - @init_in_parent def __init__(self, size: StringLike = '0805'): super().__init__() self.size = self.ArgParameter(size) diff --git a/edg/parts/ThermalSensor_FlirLepton.py b/edg/parts/ThermalSensor_FlirLepton.py index cb7870228..09e944608 100644 --- a/edg/parts/ThermalSensor_FlirLepton.py +++ b/edg/parts/ThermalSensor_FlirLepton.py @@ -3,7 +3,6 @@ class FlirLepton_Device(InternalSubcircuit, FootprintBlock, JlcPart): - @init_in_parent def __init__(self) -> None: super().__init__() self.gnd = self.Port(Ground()) @@ -88,7 +87,6 @@ class FlirLepton(Sensor, Resettable, Block): <50mK (35mK typical) NETD. Only the part number for the socket is generated, the sensor (a $100+ part) must be purchased separately. """ - @init_in_parent def __init__(self): super().__init__() self.ic = self.Block(FlirLepton_Device()) diff --git a/edg/parts/UsbPorts.py b/edg/parts/UsbPorts.py index e0fd9345e..2bfbb8dd5 100644 --- a/edg/parts/UsbPorts.py +++ b/edg/parts/UsbPorts.py @@ -35,7 +35,6 @@ class UsbCReceptacle_Device(InternalSubcircuit, FootprintBlock, JlcPart): """Raw USB Type-C Receptacle Pullup capable indicates whether this port (or more accurately, the device on the other side) can pull up the signal. In UFP (upstream-facing, device) mode the power source should pull up CC.""" - @init_in_parent def __init__(self, voltage_out: RangeLike = UsbConnector.USB2_VOLTAGE_RANGE, # allow custom PD voltage and current current_limits: RangeLike = UsbConnector.USB2_CURRENT_LIMITS, cc_pullup_capable: BoolLike = False) -> None: @@ -85,7 +84,6 @@ def contents(self): class UsbCReceptacle(UsbDeviceConnector, GeneratorBlock): """USB Type-C Receptacle that automatically generates the CC resistors if CC is not connected.""" - @init_in_parent def __init__(self, voltage_out: RangeLike = UsbConnector.USB2_VOLTAGE_RANGE, # allow custom PD voltage and current current_limits: RangeLike = UsbConnector.USB2_CURRENT_LIMITS) -> None: super().__init__() diff --git a/edg/parts/VoltageReferences.py b/edg/parts/VoltageReferences.py index 975e7321f..0f1e15a9d 100644 --- a/edg/parts/VoltageReferences.py +++ b/edg/parts/VoltageReferences.py @@ -3,7 +3,6 @@ class Ref30xx_Device(InternalSubcircuit, LinearRegulatorDevice, GeneratorBlock, JlcPart, FootprintBlock): - @init_in_parent def __init__(self, output_voltage: RangeLike): super().__init__() diff --git a/examples/TestLed/TestLed.net b/examples/TestLed/TestLed.net new file mode 100644 index 000000000..dae93f8e3 --- /dev/null +++ b/examples/TestLed/TestLed.net @@ -0,0 +1,35 @@ +(export (version D) +(components +(comp (ref "D1") + (value "led.package") + (footprint "LED_SMD:LED_0603_1608Metric") + (property (name "Sheetname") (value "led")) + (property (name "Sheetfile") (value "edg.abstract_parts.AbstractLed.IndicatorLed")) + (property (name "edg_path") (value "led.package")) + (property (name "edg_short_path") (value "led.package")) + (property (name "edg_refdes") (value "D1")) + (property (name "edg_part") (value "KT-0603R (Hubei KENTO Elec)")) + (property (name "edg_value") (value "Red 615~630nm 1.9~2.2V 0603 Light Emitting Diodes (LED) RoHS")) + (sheetpath (names "/led/") (tstamps "/02750136/")) + (tstamps "0b4e02cd")) +(comp (ref "R1") + (value "led.res") + (footprint "Resistor_SMD:R_0603_1608Metric") + (property (name "Sheetname") (value "led")) + (property (name "Sheetfile") (value "edg.abstract_parts.AbstractLed.IndicatorLed")) + (property (name "edg_path") (value "led.res")) + (property (name "edg_short_path") (value "led.res")) + (property (name "edg_refdes") (value "R1")) + (property (name "edg_part") (value "0603WAF1001T5E (UNI-ROYAL(Uniroyal Elec))")) + (property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 1kΩ 0603 Chip Resistor - Surface Mount ROHS")) + (sheetpath (names "/led/") (tstamps "/02750136/")) + (tstamps "0296014b"))) +(nets +(net (code 1) (name "led.signal") + (node (ref D1) (pin 2))) +(net (code 2) (name "gnd.gnd") + (node (ref R1) (pin 2))) +(net (code 3) (name "led.res.a") + (node (ref R1) (pin 1)) + (node (ref D1) (pin 1)))) +) \ No newline at end of file diff --git a/examples/TestLed/TestLed.svgpcb.js b/examples/TestLed/TestLed.svgpcb.js new file mode 100644 index 000000000..3a81dfb6d --- /dev/null +++ b/examples/TestLed/TestLed.svgpcb.js @@ -0,0 +1,58 @@ +const board = new PCB(); + +// led.package +const D1 = board.add(LED_0603_1608Metric, { + translate: pt(0.058, 0.029), rotate: 0, + id: 'D1' +}) +// led.res +const R1 = board.add(R_0603_1608Metric, { + translate: pt(0.058, 0.126), rotate: 0, + id: 'R1' +}) + +board.setNetlist([ + {name: "led.signal", pads: [["D1", "2"]]}, + {name: "gnd.gnd", pads: [["R1", "2"]]}, + {name: "led.res.a", pads: [["R1", "1"], ["D1", "1"]]} +]) + +const limit0 = pt(-0.07874015748031496, -0.07874015748031496); +const limit1 = pt(0.23484251968503939, 0.27283464566929133); +const xMin = Math.min(limit0[0], limit1[0]); +const xMax = Math.max(limit0[0], limit1[0]); +const yMin = Math.min(limit0[1], limit1[1]); +const yMax = Math.max(limit0[1], limit1[1]); + +const filletRadius = 0.1; +const outline = path( + [(xMin+xMax/2), yMax], + ["fillet", filletRadius, [xMax, yMax]], + ["fillet", filletRadius, [xMax, yMin]], + ["fillet", filletRadius, [xMin, yMin]], + ["fillet", filletRadius, [xMin, yMax]], + [(xMin+xMax/2), yMax], +); +board.addShape("outline", outline); + +renderPCB({ + pcb: board, + layerColors: { + "F.Paste": "#000000ff", + "F.Mask": "#000000ff", + "B.Mask": "#000000ff", + "componentLabels": "#00e5e5e5", + "outline": "#002d00ff", + "padLabels": "#ffff99e5", + "B.Cu": "#ef4e4eff", + "F.Cu": "#ff8c00cc", + }, + limits: { + x: [xMin, xMax], + y: [yMin, yMax] + }, + background: "#00000000", + mmPerUnit: 25.4 +}) + + diff --git a/examples/test_bldc_controller.py b/examples/test_bldc_controller.py index eb4c6e16f..397fd6c9f 100644 --- a/examples/test_bldc_controller.py +++ b/examples/test_bldc_controller.py @@ -5,7 +5,6 @@ class BldcConnector(Connector, Block): """Parameterizable-current connector to an external BLDC motor.""" - @init_in_parent def __init__(self, max_current: FloatLike): super().__init__() self.conn = self.Block(PassiveConnector()) diff --git a/examples/test_blinky.py b/examples/test_blinky.py index 81c56dd6b..be22671de 100644 --- a/examples/test_blinky.py +++ b/examples/test_blinky.py @@ -3,6 +3,17 @@ from edg import * +class TestLed(SimpleBoardTop): + """The actually simplest circuit, a LED connected to a dummy source.""" + def contents(self) -> None: + self.gnd = self.Block(DummyGround()) + self.src = self.Block(DummyDigitalSource()) + self.led = self.Block(IndicatorLed()) + + self.connect(self.led.signal, self.src.io) + self.connect(self.gnd.gnd, self.led.gnd) + + class TestBlinkyBasic(SimpleBoardTop): """The simplest cirucit, a microcontroller dev board with a LED.""" def contents(self) -> None: @@ -333,7 +344,6 @@ def refinements(self) -> Refinements: class LedArray(GeneratorBlock): - @init_in_parent def __init__(self, count: IntLike) -> None: super().__init__() self.ios = self.Port(Vector(DigitalSink.empty()), [Input]) @@ -544,6 +554,9 @@ def refinements(self) -> Refinements: class BlinkyTestCase(unittest.TestCase): + def test_led(self) -> None: + compile_board_inplace(TestLed) + def test_design_basic(self) -> None: compile_board_inplace(TestBlinkyBasic) # generate this netlist as a test diff --git a/examples/test_esp_programmer.py b/examples/test_esp_programmer.py index f83d1e127..9b5a7bee1 100644 --- a/examples/test_esp_programmer.py +++ b/examples/test_esp_programmer.py @@ -5,7 +5,6 @@ class EspProgrammerTc2030Inline(Connector, Block): """UART connector, follows the TXD, RXD, GND, +5 pinning of cheap CP2102 dongles.""" - @init_in_parent def __init__(self, *, pwr_current_draw: RangeLike = (0, 0)*mAmp): super().__init__() self.conn = self.Block(PinHeader254DualShroudedInline(6)) diff --git a/examples/test_fcml.py b/examples/test_fcml.py index a3e60e4b9..94aa637e3 100644 --- a/examples/test_fcml.py +++ b/examples/test_fcml.py @@ -7,7 +7,6 @@ class PowerOutConnector(Connector, Block): """Parameterized current draw voltage output connector""" - @init_in_parent def __init__(self, current: RangeLike): super().__init__() self.conn = self.Block(PassiveConnector()) @@ -23,8 +22,7 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: assert symbol_name == 'Device:D' return {'A': self.pwr_in, 'K': self.pwr_out} - @init_in_parent - def __init__(self, reverse_voltage: RangeExpr, current: RangeExpr, voltage_drop: RangeExpr) -> None: + def __init__(self, reverse_voltage: RangeLike, current: RangeLike, voltage_drop: RangeLike) -> None: super().__init__() self.pwr_out = self.Port(VoltageSource.empty(), [Output]) # forward declaration @@ -57,7 +55,6 @@ class MultilevelSwitchingCell(InternalSubcircuit, KiCadSchematicBlock, Generator - it does not generate an isolator, since signals are already ground-referenced - it does not generate a low-side bootstrap diode and cap, since voltage is provided - it does not generate a flying capacitor on the input, since that is the input cap""" - @init_in_parent def __init__(self, is_first: BoolLike = False, *, in_voltage: RangeLike, frequency: RangeLike, fet_rds: RangeLike, gate_res: RangeLike): @@ -178,7 +175,6 @@ class FcmlPowerPath(InternalSubcircuit, GeneratorBlock): TODO: Is there a way to unify this with BuckConverterPowerPath? This basically completely duplicates it, but adds a scaling factor that doesn't exist there """ - @init_in_parent def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequency: RangeLike, output_current: RangeLike, sw_current_limits: RangeLike, *, input_voltage_ripple: FloatLike, @@ -276,7 +272,6 @@ class DiscreteMutlilevelBuckConverter(PowerConditioner, GeneratorBlock): either be high or low (but not both or none). Generates a digital isolator for each gate driver that is offset from ground. """ - @init_in_parent def __init__(self, levels: IntLike, ratios: RangeLike, frequency: RangeLike, *, ripple_ratio: RangeLike = (0.2, 0.5), fet_rds: RangeLike = (0, 0.1)*Ohm): super().__init__() diff --git a/examples/test_high_switch.py b/examples/test_high_switch.py index 4b0c644d8..64c62f7b8 100644 --- a/examples/test_high_switch.py +++ b/examples/test_high_switch.py @@ -178,7 +178,6 @@ def contents(self): class LightsConnector(Connector, FootprintBlock): - @init_in_parent def __init__(self, current_draw: RangeLike = RangeExpr()) -> None: super().__init__() @@ -204,7 +203,6 @@ def contents(self): class LightsDriver(Block): - @init_in_parent def __init__(self, current_draw: RangeLike = RangeExpr()) -> None: super().__init__() diff --git a/examples/test_iot_display.py b/examples/test_iot_display.py index 136222ccd..4c78e3f40 100644 --- a/examples/test_iot_display.py +++ b/examples/test_iot_display.py @@ -8,7 +8,6 @@ class PmosHighSideSwitch(PowerSwitch): TODO: this should be generated by HighSideSwitch if the voltage is low enough, but making it smart depends on the voltage which is not available until the current is solved for (need some sort of phased generator support)""" - @init_in_parent def __init__(self, frequency: RangeLike = RangeExpr.ZERO, max_rds: FloatLike = 1*Ohm) -> None: super().__init__() diff --git a/examples/test_iot_iron.py b/examples/test_iot_iron.py index 2b1fff449..2e46e227a 100644 --- a/examples/test_iot_iron.py +++ b/examples/test_iot_iron.py @@ -9,7 +9,6 @@ class IronConnector(Connector, Block): TODO: support series heater and thermocouple, requires additional protection circuits on amps TODO: optional generation for isense_res, if not connected """ - @init_in_parent def __init__(self, *, isense_resistance: RangeLike = 22*mOhm(tol=0.05), current_draw: RangeLike=(0, 3.25)*Amp): super().__init__() self.conn = self.Block(PinHeader254(3)) diff --git a/examples/test_multimeter.py b/examples/test_multimeter.py index 97ac1f13c..aae15d72c 100644 --- a/examples/test_multimeter.py +++ b/examples/test_multimeter.py @@ -14,7 +14,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: 'V+': self.pwr, 'V-': self.gnd } - @init_in_parent def __init__(self, resistances: ArrayRangeLike): super().__init__() @@ -50,7 +49,6 @@ class MultimeterAnalog(KiCadSchematicBlock, Block): TODO: support wider ranges, to be implemented with port array support """ - @init_in_parent def __init__(self): super().__init__() @@ -92,7 +90,6 @@ def contents(self): class MultimeterCurrentDriver(KiCadSchematicBlock, Block): """Protected constant-current stage for the multimeter driver. """ - @init_in_parent def __init__(self, voltage_rating: RangeLike = RangeExpr()): super().__init__() diff --git a/examples/test_robotcrawler.py b/examples/test_robotcrawler.py index 0f0de1900..277200d34 100644 --- a/examples/test_robotcrawler.py +++ b/examples/test_robotcrawler.py @@ -7,7 +7,6 @@ class ServoFeedbackConnector(Connector, Block): """4-pin connector modeling the FS90-FB micro servo with positional feedback, https://www.pololu.com/product/3436 """ - @init_in_parent def __init__(self): super().__init__() self.conn = self.Block(PinHeader254(4)) diff --git a/examples/test_robotdriver.py b/examples/test_robotdriver.py index 0b2ba4fed..76c00d785 100644 --- a/examples/test_robotdriver.py +++ b/examples/test_robotdriver.py @@ -4,7 +4,6 @@ class MotorConnector(Connector, Block): - @init_in_parent def __init__(self, current_draw: RangeLike): super().__init__() self.conn = self.Block(PassiveConnector()) @@ -18,7 +17,6 @@ def __init__(self, current_draw: RangeLike): class PwmConnector(Connector, Block): - @init_in_parent def __init__(self, current_draw: RangeLike): super().__init__() self.conn = self.Block(PinHeader254()) @@ -34,7 +32,6 @@ def __init__(self, current_draw: RangeLike): class LedConnector(Connector, Block): """Connector for external WS2812s.""" - @init_in_parent def __init__(self, num_leds: FloatLike = 0): super().__init__() self.conn = self.Block(PassiveConnector()) diff --git a/examples/test_robotowl.py b/examples/test_robotowl.py index 4061887b6..ff0cb5a46 100644 --- a/examples/test_robotowl.py +++ b/examples/test_robotowl.py @@ -7,7 +7,6 @@ class PhotodiodeSensor(LightSensor, KiCadSchematicBlock, Block): """Simple photodiode-based light sensor""" - @init_in_parent def __init__(self) -> None: super().__init__() self.gnd = self.Port(Ground.empty(), [Common]) diff --git a/examples/test_simon.py b/examples/test_simon.py index 28e4813fa..b342d3116 100644 --- a/examples/test_simon.py +++ b/examples/test_simon.py @@ -4,7 +4,6 @@ class DomeButtonConnector(Connector, FootprintBlock): - @init_in_parent def __init__(self) -> None: super().__init__() diff --git a/examples/test_usb_source_measure.py b/examples/test_usb_source_measure.py index ce73202c0..784daab69 100644 --- a/examples/test_usb_source_measure.py +++ b/examples/test_usb_source_measure.py @@ -29,7 +29,6 @@ def __init__(self): class SourceMeasureRangingCell(Interface, KiCadSchematicBlock): - @init_in_parent def __init__(self, resistance: RangeLike): super().__init__() self.resistance = self.ArgParameter(resistance) @@ -77,7 +76,6 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]: 'V+': self.pwr, 'V-': self.gnd } - @init_in_parent def __init__(self, resistances: ArrayRangeLike, currents: ArrayRangeLike): super().__init__() @@ -139,7 +137,6 @@ def symbol_pinning(self, symbol_name: str) -> Mapping[str, BasePort]: '1': self.control, '3': self.out, 'V+': self.pwr, 'V-': self.gnd } - @init_in_parent def __init__(self, current: RangeLike, rds_on: RangeLike): super().__init__() @@ -208,7 +205,6 @@ def symbol_pinning(self, symbol_name: str) -> Mapping[str, BasePort]: assert symbol_name in ('Simulation_SPICE:OPAMP', 'edg_importable:Opamp') return {'+': self.actual, '-': self.target, '3': self.output, 'V+': self.pwr, 'V-': self.gnd} - @init_in_parent def __init__(self, diode_spec: StringLike, output_resistance: RangeLike, input_resistance: RangeLike, *, series: IntLike = 24, tolerance: FloatLike = 0.01): super().__init__() @@ -299,7 +295,6 @@ def generate(self) -> None: class SourceMeasureControl(InternalSubcircuit, KiCadSchematicBlock, Block): """Analog feedback circuit for the source-measure unit """ - @init_in_parent def __init__(self, current: RangeLike, rds_on: RangeLike): super().__init__() diff --git a/examples/test_usb_uart.py b/examples/test_usb_uart.py index ebe596704..b26f674f7 100644 --- a/examples/test_usb_uart.py +++ b/examples/test_usb_uart.py @@ -5,7 +5,6 @@ class UartConnector(Connector, Block): """UART connector, follows the TXD, RXD, GND, +5 pinning of cheap CP2102 dongles.""" - @init_in_parent def __init__(self, *, pwr_current_draw: RangeLike = (0, 0)*mAmp): super().__init__() self.conn = self.Block(PassiveConnector())