Skip to content

Commit b8aca1c

Browse files
committed
More specific return type for root_instrument
1 parent 86273d9 commit b8aca1c

5 files changed

Lines changed: 18 additions & 6 deletions

File tree

src/qcodes/instrument/channel.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
from typing_extensions import Unpack
2828

29+
from .instrument import Instrument
2930
from .instrument_base import InstrumentBaseKWArgs
3031

3132

@@ -86,8 +87,14 @@ def parent(self) -> _TIB_co:
8687
return self._parent
8788

8889
@property
89-
def root_instrument(self) -> InstrumentBase:
90-
return self._parent.root_instrument
90+
def root_instrument(self) -> Instrument:
91+
# the root instrument is the top level parent of this module, we need to
92+
# go up the parent hierarchy until we find an object that returns itself as the parent, this should be the root instrument. We also
93+
# this is required to be an Instrument.
94+
# Once 3.13 is the minimum supported version
95+
# consider replacing with a generic parameter with a default
96+
# value of Instrument.
97+
return cast("Instrument", self._parent.root_instrument)
9198

9299
@property
93100
def name_parts(self) -> list[str]:

src/qcodes/instrument/instrument_base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
if TYPE_CHECKING:
2020
from collections.abc import Callable, Mapping, Sequence
21-
from typing import NotRequired
21+
from typing import NotRequired, Self
2222

2323
from qcodes.instrument.channel import ChannelTuple, InstrumentModule
2424
from qcodes.logger.instrument_logger import InstrumentLoggerAdapter
@@ -579,7 +579,7 @@ def ancestors(self) -> tuple[InstrumentBase, ...]:
579579
return (self,)
580580

581581
@property
582-
def root_instrument(self) -> InstrumentBase:
582+
def root_instrument(self) -> Self:
583583
"""
584584
The topmost parent of this module.
585585

tests/drivers/keysight_b1500/b1500_driver_tests/test_b1517a_smu.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ def test_iv_sweep_delay(smu: KeysightB1517A) -> None:
433433
smu.iv_sweep.step_delay(0.01)
434434
smu.iv_sweep.trigger_delay(0.1)
435435
smu.iv_sweep.measure_delay(15.4)
436-
436+
assert isinstance(mainframe, MagicMock)
437437
mainframe.write.assert_has_calls(
438438
[
439439
call("WT 43.12,0.0,0.0,0.0,0.0"),

tests/drivers/keysight_b1500/b1500_driver_tests/test_b1520a_cmu.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def test_get_post_sweep_voltage_cond(cmu: KeysightB1520A) -> None:
179179

180180
def test_cv_sweep_delay(cmu: KeysightB1520A) -> None:
181181
mainframe = cmu.root_instrument
182-
182+
assert isinstance(mainframe, MagicMock)
183183
mainframe.ask.return_value = "WTDCV0.0,0.0,0.0,0.0,0.0"
184184

185185
cmu.cv_sweep.hold_time(1.0)
@@ -192,6 +192,7 @@ def test_cv_sweep_delay(cmu: KeysightB1520A) -> None:
192192

193193
def test_cmu_sweep_steps(cmu: KeysightB1520A) -> None:
194194
mainframe = cmu.root_instrument
195+
assert isinstance(mainframe, MagicMock)
195196
mainframe.ask.return_value = "WDCV3,1,0.0,0.0,1"
196197
cmu.cv_sweep.sweep_start(2.0)
197198
cmu.cv_sweep.sweep_end(4.0)
@@ -208,6 +209,7 @@ def test_cv_sweep_voltages(cmu: KeysightB1520A) -> None:
208209
end = 1.0
209210
steps = 5
210211
return_string = f"WDCV3,1,{start},{end},{steps}"
212+
assert isinstance(mainframe, MagicMock)
211213
mainframe.ask.return_value = return_string
212214

213215
cmu.cv_sweep.sweep_start(start)
@@ -226,6 +228,7 @@ def test_sweep_modes(cmu: KeysightB1520A) -> None:
226228
steps = 5
227229
mode = constants.SweepMode.LINEAR_TWO_WAY
228230
return_string = f"WDCV3,{mode},{start},{end},{steps}"
231+
assert isinstance(mainframe, MagicMock)
229232
mainframe.ask.return_value = return_string
230233

231234
cmu.cv_sweep.sweep_start(start)
@@ -249,6 +252,7 @@ def test_run_sweep(cmu: KeysightB1520A) -> None:
249252
f"0.0000;WDCV3,"
250253
f"1,{start},{end},{steps};ACT0,1"
251254
)
255+
assert isinstance(mainframe, MagicMock)
252256
mainframe.ask.return_value = return_string
253257
cmu.setup_fnc_already_run = True
254258
cmu.impedance_model(constants.IMP.MeasurementMode.G_X)

tests/drivers/keysight_b1500/b1500_driver_tests/test_sampling_measurement.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def test_sampling_measurement(
8383
actual_data = smu.sampling_measurement_trace.get()
8484

8585
np.testing.assert_allclose(actual_data, data_to_return, atol=1e-3)
86+
assert isinstance(smu.root_instrument.ask, Mock)
8687
smu.root_instrument.ask.assert_called_with("XE")
8788

8889

0 commit comments

Comments
 (0)