microsoft / Qcodes

Modular data acquisition framework

Home Page:http://microsoft.github.io/Qcodes/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

InstrumentModule keeps appending to name_parts when Instrument is a Mock

haroldmeerwaldt opened this issue · comments

Hi there,

I am encountering the following:
InstrumentModule keeps appending to name_parts at each call when Instrument is a Mock.

This does not happen when an actual Instrument is passed as parent (set use_mock=False).

Steps to reproduce

from unittest.mock import Mock

from qcodes import Instrument
from qcodes.instrument import InstrumentModule

use_mock = True
if use_mock:
    inst = Mock()
    inst.name_parts = ["inst"]
else:
    inst = Instrument("inst")

im0 = InstrumentModule(inst, "im0")
im1 = InstrumentModule(inst, "im1")

for _ in range(3):
    print(f"{im0.name_parts=}")

for _ in range(3):
    print(f"{im1.name_parts=}")

for _ in range(3):
    print(f"{inst.name_parts=}")

for _ in range(3):
    print(f"{inst.name=}")

for _ in range(3):
    print(f"{im0.name=}")

for _ in range(3):
    print(f"{im1.name=}")

Expected behaviour

I expected the name of the InstrumentModules to be "inst_im0" and "inst_im0"

Actual behaviour

What happens is that the "_im0" gets appended to the name each time name_parts of the InstrumentModule is called:

im0.name_parts=['inst', 'im0']
im0.name_parts=['inst', 'im0', 'im0']
im0.name_parts=['inst', 'im0', 'im0', 'im0']
im1.name_parts=['inst', 'im0', 'im0', 'im0', 'im1']
im1.name_parts=['inst', 'im0', 'im0', 'im0', 'im1', 'im1']
im1.name_parts=['inst', 'im0', 'im0', 'im0', 'im1', 'im1', 'im1']
inst.name_parts=['inst', 'im0', 'im0', 'im0', 'im1', 'im1', 'im1']
inst.name_parts=['inst', 'im0', 'im0', 'im0', 'im1', 'im1', 'im1']
inst.name_parts=['inst', 'im0', 'im0', 'im0', 'im1', 'im1', 'im1']
inst.name=<Mock name='mock.name' id='2081958499568'>
inst.name=<Mock name='mock.name' id='2081958499568'>
inst.name=<Mock name='mock.name' id='2081958499568'>
im0.name='inst_im0_im0_im0_im1_im1_im1_im0'
im0.name='inst_im0_im0_im0_im1_im1_im1_im0_im0'
im0.name='inst_im0_im0_im0_im1_im1_im1_im0_im0_im0'
im1.name='inst_im0_im0_im0_im1_im1_im1_im0_im0_im0_im1'
im1.name='inst_im0_im0_im0_im1_im1_im1_im0_im0_im0_im1_im1'
im1.name='inst_im0_im0_im0_im1_im1_im1_im0_im0_im0_im1_im1_im1'

The .name_parts property of InstrumentModule is:

@property
def name_parts(self) -> List[str]:
    name_parts = self._parent.name_parts
    name_parts.append(self.short_name)
    return name_parts

I think this is okay when self._parent.name_parts is a property and name_parts becomes a copy. If you put in an instrument whose .name_parts is not a property, name_parts becomes a reference and self.short_name is appended to the instrument's .name_parts at each call.

I propose to replace this function by:

@property
def name_parts(self) -> list[str]:
    return self._parent.name_parts + [self.short_name]

System

Windows 10
qcodes 0.33.0

@haroldmeerwaldt thank you for describing and reporting! sounds fair! would you be willing to open a PR with this change?

we could also trick a bit and don't depends on _parent.name_parts being a list by doing:

@property
def name_parts(self) -> list[str]:
    return list(self._parent.name_parts) + [self.short_name]

The extra list sounds good, no need to depend on the static typing. I'll work on a PR.

@astafan8 do you also want a test to prevent this behaviour from re-occurring? Or is this such a special case, and you don't want to unit test properties? (If yes, it goes here?: https://github.com/QCoDeS/Qcodes/blob/master/qcodes/tests/test_channels.py#L72)

Hi @astafan8,

I am sorry, this issue has actually already been fixed:
03ccdc1

I thought I had the latest qcodes, but some other package required a lower version. Apologies.

No worries. I will go ahead and mark this as closed by #4257 then