Instantiating an Instrument using __new__ and __init__
rsokolewicz opened this issue · 2 comments
We are trying to implement methods that serialize an instance of an Instrument (e.g. write it to a JSON file) and deserialize the JSON file (re-instantiate the Instrument using info inside the JSON). At first glance, everything seemed to work, but we found out that we could create multiple Instruments that share the same name.
For example,
i0 = Instrument("i0")
i1 = Instrument.__new__(Instrument)
i1.__init__("i0")
We can add parameters and submodules to i1
, but it looks like the instantiation is not done correctly. First of all i1
is created with an already known name, so it should raise a KeyError, but it's also not recorded as an instance. Running the following snippet
p0 = Instrument.__new__(Instrument)
p0.__init__("p0")
Instrument.instances()
returns an empty list.
Is this due to some misunderstanding of how python instantiates objects, or is it related to qcodes?
My initial reaction would be to consider calling new directly unsupported and I would prefer to avoid that and find a way for you to do what you want without having to do that.
The way I understand initilization is basically that
Instrument(name="name")
will invoke __call__
on the metaclass of the instrument this will in turn invoke first __new__
on the metaclass and then call __init__
on the class it self. You can't really find this code in python it self since this is done in the c-code and not in pure python. In our metaclass for instruments https://github.com/QCoDeS/Qcodes/blob/master/qcodes/instrument/instrument_meta.py we effectively hook into this to check that the instrument does not have abstract parameters and that its name is free before registering it. That effectively means that if you do not execute __call__
on the metaclass this will not happen
Thanks for clearing it up :) We will try another way then. Closing this issue now!