From c3288dcdc9b3f8203de452b30e14e91b868212aa Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:03:29 +0200 Subject: [PATCH 001/104] Minimal typing config --- qcodes/config/config.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qcodes/config/config.py b/qcodes/config/config.py index 767832efe35..9a0392acf0e 100644 --- a/qcodes/config/config.py +++ b/qcodes/config/config.py @@ -9,6 +9,7 @@ from pathlib import Path import jsonschema +from typing import Dict, Union logger = logging.getLogger(__name__) @@ -87,8 +88,8 @@ class Config(): defaults = None defaults_schema = None - _diff_config = {} - _diff_schema = {} + _diff_config = {} # type: Dict[str, dict] + _diff_schema = {} # type: Dict[str, dict] def __init__(self): self.defaults, self.defaults_schema = self.load_default() From 11e15eeb2284e64dadc346794af198398cf6cae5 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:03:54 +0200 Subject: [PATCH 002/104] Minimal typing helpers --- qcodes/utils/helpers.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qcodes/utils/helpers.py b/qcodes/utils/helpers.py index 3cbfcb993b8..ce8c5be1586 100644 --- a/qcodes/utils/helpers.py +++ b/qcodes/utils/helpers.py @@ -8,10 +8,11 @@ from collections import Iterator, Sequence, Mapping from copy import deepcopy +from typing import Dict, List import numpy as np -_tprint_times = {} +_tprint_times= {} # type: Dict[str, float] class NumpyJSONEncoder(json.JSONEncoder): @@ -319,9 +320,9 @@ class DelegateAttributes: 2. keys of each dict in delegate_attr_dicts (in order) 3. attributes of each object in delegate_attr_objects (in order) """ - delegate_attr_dicts = [] - delegate_attr_objects = [] - omit_delegate_attrs = [] + delegate_attr_dicts = [] # type: List[str] + delegate_attr_objects = [] # type: List[str] + omit_delegate_attrs = [] # type: List[str] def __getattr__(self, key): if key in self.omit_delegate_attrs: From fc9227d94e5820456a08417990edc242867e82aa Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:04:59 +0200 Subject: [PATCH 003/104] location towards minimal typing --- qcodes/data/location.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/data/location.py b/qcodes/data/location.py index 91af8594cf1..db41175fba0 100644 --- a/qcodes/data/location.py +++ b/qcodes/data/location.py @@ -83,7 +83,7 @@ class FormatLocation: as '{date:%Y-%m-%d}' or '{counter:03}' """ - default_fmt = config['core']['default_fmt'] + default_fmt = config['core']['default_fmt'] # type: str def __init__(self, fmt=None, fmt_date=None, fmt_time=None, fmt_counter=None, record=None): From e1af56f33deeb9cc3457ca40d445127dc643499d Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:05:28 +0200 Subject: [PATCH 004/104] instrument base minimal typing --- qcodes/instrument/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index 24f1efcaa52..801d78eda5d 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -4,6 +4,7 @@ import time import warnings import weakref +from typing import Dict from qcodes.utils.metadata import Metadatable from qcodes.utils.helpers import DelegateAttributes, strip_attrs, full_class @@ -42,7 +43,7 @@ class Instrument(Metadatable, DelegateAttributes): shared_kwargs = () - _all_instruments = {} + _all_instruments = {} # type: Dict[str, weakref.ref] def __init__(self, name, **kwargs): self._t0 = time.time() From 594811922ce9e98d1526dca410bd7d1cf4851f41 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:06:03 +0200 Subject: [PATCH 005/104] Channel improve typing --- qcodes/instrument/channel.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index f5c44110124..2982ae10788 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -1,5 +1,5 @@ """ Base class for the channel of an instrument """ -from typing import List, Tuple, Union +from typing import List, Tuple, Union, Optional from .base import Instrument from .parameter import MultiParameter, ArrayParameter @@ -100,7 +100,7 @@ class MultiChannelInstrumentParameter(MultiParameter): param_name(str): Name of the multichannel parameter """ - def __init__(self, channels: Union[List, Tuple], param_name, *args, **kwargs): + def __init__(self, channels: Union[List, Tuple], param_name, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self._channels = channels self._param_name = param_name @@ -167,9 +167,10 @@ class ChannelList(Metadatable): """ - def __init__(self, parent, name, chan_type: type, chan_list=None, - snapshotable=True, - multichan_paramclass: type=MultiChannelInstrumentParameter): + def __init__(self, parent, name, chan_type: type, + chan_list: Optional[List[InstrumentChannel]]=None, + snapshotable: bool=True, + multichan_paramclass: type=MultiChannelInstrumentParameter) -> None: super().__init__() self._parent = parent @@ -191,7 +192,7 @@ def __init__(self, parent, name, chan_type: type, chan_list=None, # This will eventually become a locked tuple. if chan_list is None: self._locked = False - self._channels = [] + self._channels = [] # type: Union[List[InstrumentChannel],Tuple[InstrumentChannel]] else: self._locked = True self._channels = tuple(chan_list) From 255dc01c264a9b0fb69c525268407baad331e8c7 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:06:52 +0200 Subject: [PATCH 006/104] typing driver test --- qcodes/instrument_drivers/test.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/test.py b/qcodes/instrument_drivers/test.py index 1169792f513..1849c263ee4 100644 --- a/qcodes/instrument_drivers/test.py +++ b/qcodes/instrument_drivers/test.py @@ -1,5 +1,5 @@ import unittest - +from typing import Optional ''' This module defines: @@ -26,7 +26,8 @@ class DriverTestCase(unittest.TestCase): - driver = None # override this in a subclass + # override this in a subclass + driver = None # type: Optional[type] @classmethod def setUpClass(cls): From 8b21b5bcce6035f005b22230234cc3eb0377caca Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:07:33 +0200 Subject: [PATCH 007/104] test_helpers make this valid python code --- qcodes/tests/test_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/tests/test_helpers.py b/qcodes/tests/test_helpers.py index f55827d0c9c..aae4a7df0be 100644 --- a/qcodes/tests/test_helpers.py +++ b/qcodes/tests/test_helpers.py @@ -104,7 +104,7 @@ def f_async_old(): class TestIsSequence(TestCase): - def a_func(): + def a_func(self): raise RuntimeError('this function shouldn\'t get called') class AClass(): From df2bae774d653d55babd2e6f61084ebcc15c9f3d Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:08:12 +0200 Subject: [PATCH 008/104] improve typing parameter --- qcodes/tests/test_parameter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/test_parameter.py b/qcodes/tests/test_parameter.py index f709eaab9a0..6d09a46833f 100644 --- a/qcodes/tests/test_parameter.py +++ b/qcodes/tests/test_parameter.py @@ -3,6 +3,7 @@ """ from collections import namedtuple from unittest import TestCase +from typing import Tuple from qcodes import Function from qcodes.instrument.parameter import ( @@ -53,7 +54,7 @@ def set(self, v): None, # no instrument at all namedtuple('noname', '')(), # no .name namedtuple('blank', 'name')('') # blank .name -) +) # type: Tuple named_instrument = namedtuple('yesname', 'name')('astro') From 975f6aab0bc1ec235e462e0359730db368202bf7 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:08:41 +0200 Subject: [PATCH 009/104] avoid overwriting time --- qcodes/tests/test_location_provider.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/test_location_provider.py b/qcodes/tests/test_location_provider.py index 43465bcc617..8dabea25b6c 100644 --- a/qcodes/tests/test_location_provider.py +++ b/qcodes/tests/test_location_provider.py @@ -23,11 +23,11 @@ def test_missing(self): def _default(time: datetime, formatter: FormatLocation, counter:str, name: str): date = time.strftime(formatter.fmt_date) - time = time.strftime(formatter.fmt_time) + mytime = time.strftime(formatter.fmt_time) fmted = formatter.formatter.format(formatter.default_fmt, date=date, counter=counter, - time=time, + time=mytime, name=name) return fmted From 988dd89033b0106e6fd9c3c1184db68f878b04a1 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:10:57 +0200 Subject: [PATCH 010/104] work around for missing imports in mypy --- qcodes/instrument_drivers/Spectrum/pyspcm.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/Spectrum/pyspcm.py b/qcodes/instrument_drivers/Spectrum/pyspcm.py index b278ca7d1fb..11bbe19b06c 100644 --- a/qcodes/instrument_drivers/Spectrum/pyspcm.py +++ b/qcodes/instrument_drivers/Spectrum/pyspcm.py @@ -1,6 +1,7 @@ import os import platform -import sys +import sys +from ctypes import c_int8, c_int16, c_int32,c_int64, POINTER, c_uint8, c_uint16, c_uint32, c_uint64, c_void_p, windll, cdll, c_char_p from ctypes import * # load registers for easier access From 6df7185030b26ae7cf6615f9cbfe551b826f34e1 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:13:52 +0200 Subject: [PATCH 011/104] keysight avoid mixing modules and None --- qcodes/instrument_drivers/keysight/test_suite.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/qcodes/instrument_drivers/keysight/test_suite.py b/qcodes/instrument_drivers/keysight/test_suite.py index db663f8d88f..fe309a9c45b 100644 --- a/qcodes/instrument_drivers/keysight/test_suite.py +++ b/qcodes/instrument_drivers/keysight/test_suite.py @@ -4,13 +4,16 @@ from .M3201A import Keysight_M3201A from .M3300A import M3300A_AWG from .SD_common.SD_Module import SD_Module + SD_Module_found = True + Keysight_M3201A_found = True + M3300A_AWG_found = True except ImportError: - SD_Module = None - Keysight_M3201A = None - M3300A_AWG = None + SD_Module_found = False + Keysight_M3201A_found = False + M3300A_AWG_found = False -@unittest.skipIf(not SD_Module, "SD_Module tests requires the keysightSD1 module") +@unittest.skipIf(not SD_Module_found, "SD_Module tests requires the keysightSD1 module") class TestSD_Module(DriverTestCase): """ Tis is a test suite for testing the general Keysight SD_Module driver. @@ -40,7 +43,7 @@ def test_chassis_and_slot(self): self.assertEqual(serial_number_test, serial_number) -@unittest.skipIf(not Keysight_M3201A, "Keysight_M3201A tests requires the keysightSD1 module") +@unittest.skipIf(not Keysight_M3201A_found, "Keysight_M3201A tests requires the keysightSD1 module") class TestKeysight_M3201A(DriverTestCase): """ This is a test suite for testing the Signadyne M3201A AWG card driver. @@ -279,7 +282,7 @@ def test_PXI_trigger(self): self.instrument.pxi_trigger_number_0.set(cur_pxi) -@unittest.skipIf(not M3300A_AWG, "M3300A_AWG tests requires the keysightSD1 module") +@unittest.skipIf(not M3300A_AWG_found, "M3300A_AWG tests requires the keysightSD1 module") class TestKeysight_M3300A(DriverTestCase): """ This is a test suite for testing the Signadyne M3201A AWG card driver. From 8221bb31a884a91e1eb588a34808d782f90a5e36 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 11:23:47 +0200 Subject: [PATCH 012/104] h2py fix python2 syntax --- qcodes/instrument_drivers/Spectrum/py_header/h2py.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/Spectrum/py_header/h2py.py b/qcodes/instrument_drivers/Spectrum/py_header/h2py.py index 3644f5512dc..0d63059ac3c 100644 --- a/qcodes/instrument_drivers/Spectrum/py_header/h2py.py +++ b/qcodes/instrument_drivers/Spectrum/py_header/h2py.py @@ -135,7 +135,7 @@ def process(fp, outfp, env = {}): ok = 0 stmt = '%s = %s\n' % (name, body) try: - exec stmt in env + exec(stmt, env) except: sys.stderr.write('Skipping: %s' % stmt) else: @@ -147,7 +147,7 @@ def process(fp, outfp, env = {}): body = pytify(body) stmt = 'def %s(%s): return %s\n' % (macro, arg, body) try: - exec stmt in env + exec(stmt, env) except: sys.stderr.write('Skipping: %s' % stmt) else: From 1eb827326d92ebfba2c080bbcefc490ffb6f9b07 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:43:22 +0200 Subject: [PATCH 013/104] Travis run mypy --- .travis.yml | 1 + test_requirements.txt | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f51396fff9d..1f02348cc90 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,7 @@ install: script: - cd qcodes - py.test --cov=qcodes --cov-report xml --cov-config=.coveragerc + - mypy qcode --ignore-missing-imports --follow-imports=skip - | cd ../docs make html-api diff --git a/test_requirements.txt b/test_requirements.txt index 6e769b3eccf..2ae12a1038c 100644 --- a/test_requirements.txt +++ b/test_requirements.txt @@ -2,4 +2,5 @@ coverage pytest-cov pytest codacy-coverage -hypothesis \ No newline at end of file +hypothesis +mypy From 08f2bf1b849d41c037c74612de27a178866a238b Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:45:16 +0200 Subject: [PATCH 014/104] data_set minimal typing --- qcodes/data/data_set.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/data/data_set.py b/qcodes/data/data_set.py index d5407807b5d..64260356bdf 100644 --- a/qcodes/data/data_set.py +++ b/qcodes/data/data_set.py @@ -166,7 +166,7 @@ class DataSet(DelegateAttributes): default_formatter = GNUPlotFormat() location_provider = FormatLocation() - background_functions = OrderedDict() + background_functions = OrderedDict() # type: OrderedDict def __init__(self, location=None, arrays=None, formatter=None, io=None, write_period=5): From 93d9d5213a739e9308f847c3ccd18b64a12f5945 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:47:26 +0200 Subject: [PATCH 015/104] location silence warning --- qcodes/data/location.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qcodes/data/location.py b/qcodes/data/location.py index db41175fba0..ff0b6ae2a70 100644 --- a/qcodes/data/location.py +++ b/qcodes/data/location.py @@ -83,7 +83,9 @@ class FormatLocation: as '{date:%Y-%m-%d}' or '{counter:03}' """ - default_fmt = config['core']['default_fmt'] # type: str + default_fmt = config['core']['default_fmt'] # type: ignore + # silence warning about the type of config, not sure how to do this + # correctly def __init__(self, fmt=None, fmt_date=None, fmt_time=None, fmt_counter=None, record=None): From dfd16efdbd0b3858aa412108d389b43dedbefc36 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:48:06 +0200 Subject: [PATCH 016/104] channel silence warning --- qcodes/instrument/channel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index 2982ae10788..6c1c1b82029 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -192,7 +192,8 @@ def __init__(self, parent, name, chan_type: type, # This will eventually become a locked tuple. if chan_list is None: self._locked = False - self._channels = [] # type: Union[List[InstrumentChannel],Tuple[InstrumentChannel]] + self._channels = [] # type: Union[List[InstrumentChannel],Tuple[InstrumentChannel], Tuple[InstrumentChannel, ...]] + # No idea why the last type is needed should never happen else: self._locked = True self._channels = tuple(chan_list) From d62023faf480a995f45800586c4ad2c1e4a3518c Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:50:18 +0200 Subject: [PATCH 017/104] work around mypy issue --- qcodes/instrument_drivers/devices.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/devices.py b/qcodes/instrument_drivers/devices.py index ff8f32da126..c526009832c 100644 --- a/qcodes/instrument_drivers/devices.py +++ b/qcodes/instrument_drivers/devices.py @@ -73,7 +73,8 @@ def __init__(self, self._meta_attrs.extend(["division_value"]) def set(self, value: Union[int, float]) -> None: - instrument_value = value * self.division_value + instrument_value = value * self.division_value # type: ignore + # disable type check due to https://github.com/python/mypy/issues/2128 self._save_val(value) self.v1.set(instrument_value) From 05f85bd8d8e4cddb052092c82da77adcb6e5c0c5 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:51:59 +0200 Subject: [PATCH 018/104] parameter fix setpoints not defined --- qcodes/instrument/parameter.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 612a72ba353..3bbae6e7e77 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -1188,6 +1188,7 @@ def __init__(self, parameters, name, label=None, if unit is None: unit = units self.parameter.unit = unit + self.setpoints=[] # endhack self.parameters = parameters self.sets = [parameter.set for parameter in self.parameters] @@ -1246,14 +1247,14 @@ def sweep(self, *array: numpy.ndarray): {} dimensional array, got a {} dimensional array. \ """ try: - if array.shape[1] != self.dimensionality: + if array.shape[1] != self.dimensionality: # type: ignore raise ValueError(_error_msg.format(self.dimensionality, - array.shape[1])) + array.shape[1])) # type: ignore except KeyError: # this means the array is 1d raise ValueError(_error_msg.format(self.dimensionality, 1)) - new.setpoints = array.tolist() + new.setpoints = array.tolist() # type: ignore return new def _aggregate(self, *vals): From f8317cb3cf3ae83d586d3087210e87e2410a6365 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:52:26 +0200 Subject: [PATCH 019/104] make skipping code more robust --- .../instrument_drivers/keysight/test_suite.py | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/qcodes/instrument_drivers/keysight/test_suite.py b/qcodes/instrument_drivers/keysight/test_suite.py index fe309a9c45b..bcd96d28ebd 100644 --- a/qcodes/instrument_drivers/keysight/test_suite.py +++ b/qcodes/instrument_drivers/keysight/test_suite.py @@ -1,17 +1,22 @@ from qcodes.instrument_drivers.test import DriverTestCase import unittest +from typing import Optional + try: from .M3201A import Keysight_M3201A + Keysight_M3201A_found = True +except ImportError: + Keysight_M3201A_found = False +try: from .M3300A import M3300A_AWG + M3300A_AWG_found = True +except ImportError: + M3300A_AWG_found = False +try: from .SD_common.SD_Module import SD_Module SD_Module_found = True - Keysight_M3201A_found = True - M3300A_AWG_found = True except ImportError: SD_Module_found = False - Keysight_M3201A_found = False - M3300A_AWG_found = False - @unittest.skipIf(not SD_Module_found, "SD_Module tests requires the keysightSD1 module") class TestSD_Module(DriverTestCase): @@ -21,8 +26,8 @@ class TestSD_Module(DriverTestCase): This test suit is only used during the development of the general SD_Module driver. In a real-life scenario, no direct instances will be made from this class, but rather instances of either SD_AWG or SD_DIG. """ - - driver = SD_Module + if SD_Module_found: + driver = SD_Module @classmethod def setUpClass(cls): @@ -62,8 +67,8 @@ class TestKeysight_M3201A(DriverTestCase): We can however test for ValueErrors which is a useful safety test. """ - - driver = Keysight_M3201A + if Keysight_M3201A_found: + driver = Keysight_M3201A @classmethod def setUpClass(cls): @@ -301,8 +306,8 @@ class TestKeysight_M3300A(DriverTestCase): We can however test for ValueErrors which is a useful safety test. """ - - driver = M3300A_AWG + if M3300A_AWG_found: + driver = M3300A_AWG @classmethod def setUpClass(cls): From 4fe9dc2603b749628b82599a43897de1d6ade833 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:52:54 +0200 Subject: [PATCH 020/104] Test visa fix typing issue --- qcodes/tests/test_visa.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/test_visa.py b/qcodes/tests/test_visa.py index bbe6e92141a..f9b6d4b321f 100644 --- a/qcodes/tests/test_visa.py +++ b/qcodes/tests/test_visa.py @@ -30,16 +30,18 @@ class MockVisaHandle: ''' def __init__(self): self.state = 0 + self.closed = False def clear(self): self.state = 0 def close(self): # make it an error to ask or write after close - self.write = None - self.ask = None + self.closed = True def write(self, cmd): + if self.closed: + raise RuntimeError("Trying to write to a closed instrument") num = float(cmd.split(':')[-1]) self.state = num @@ -54,6 +56,8 @@ def write(self, cmd): return len(cmd), ret_code def ask(self, cmd): + if self.closed: + raise RuntimeError("Trying to ask a closed instrument") if self.state > 10: raise ValueError("I'm out of fingers") return self.state From 9f455839b73e68386c27ad4d1d7d4dfc78780187 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:53:16 +0200 Subject: [PATCH 021/104] h2py minimal typing --- qcodes/instrument_drivers/Spectrum/py_header/h2py.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/Spectrum/py_header/h2py.py b/qcodes/instrument_drivers/Spectrum/py_header/h2py.py index 0d63059ac3c..2276d2bc26b 100644 --- a/qcodes/instrument_drivers/Spectrum/py_header/h2py.py +++ b/qcodes/instrument_drivers/Spectrum/py_header/h2py.py @@ -40,7 +40,7 @@ p_hex = re.compile(r"0x([0-9a-fA-F]+)L?") -filedict = {} +filedict = {} # type: dict importable = {} try: From 978a012c3432984f1db83a6a61bf60f4d649e0e8 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:53:47 +0200 Subject: [PATCH 022/104] M3201A fix mypy import issue --- qcodes/instrument_drivers/keysight/M3201A.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/keysight/M3201A.py b/qcodes/instrument_drivers/keysight/M3201A.py index ee6ba180411..d207c732d9b 100644 --- a/qcodes/instrument_drivers/keysight/M3201A.py +++ b/qcodes/instrument_drivers/keysight/M3201A.py @@ -2,7 +2,7 @@ # from functools import partial # # from .SD_common.SD_Module import * -from .SD_common.SD_AWG import * +from .SD_common.SD_AWG import SD_AWG class Keysight_M3201A(SD_AWG): From a70a29309c4c3ee56071730759ce2dc68d08682a Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 14:54:48 +0200 Subject: [PATCH 023/104] remove unused shared_kwargs --- qcodes/tests/instrument_mocks.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/qcodes/tests/instrument_mocks.py b/qcodes/tests/instrument_mocks.py index c9f2c669be1..c52986b5e84 100644 --- a/qcodes/tests/instrument_mocks.py +++ b/qcodes/tests/instrument_mocks.py @@ -55,8 +55,6 @@ class MockMetaParabola(Instrument): ''' Test for a meta instrument, has a tunable gain knob ''' - # TODO (giulioungaretti) remove unneded shared_kwargs - shared_kwargs = ['mock_parabola_inst'] def __init__(self, name, mock_parabola_inst, **kw): super().__init__(name, **kw) From 0ad7eb00579483c31323c0c70f5365670076e8c2 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 15:08:48 +0200 Subject: [PATCH 024/104] typo --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1f02348cc90..afce450f583 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,9 +35,11 @@ install: script: - cd qcodes - py.test --cov=qcodes --cov-report xml --cov-config=.coveragerc - - mypy qcode --ignore-missing-imports --follow-imports=skip - | - cd ../docs + cd .. + mypy qcodes --ignore-missing-imports --follow-imports=skip + - | + cd docs make html-api - cd .. From 0049576d69abb43416c4fb638417e31a8d71fbd2 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 28 Jun 2017 15:31:21 +0200 Subject: [PATCH 025/104] Annotate return type of init --- qcodes/instrument_drivers/stanford_research/SR830.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/stanford_research/SR830.py b/qcodes/instrument_drivers/stanford_research/SR830.py index b7d315cd3c8..26ff546cee4 100644 --- a/qcodes/instrument_drivers/stanford_research/SR830.py +++ b/qcodes/instrument_drivers/stanford_research/SR830.py @@ -15,7 +15,7 @@ class ChannelBuffer(ArrayParameter): The instrument natively supports this in its TRCL call. """ - def __init__(self, name: str, instrument: 'SR830', channel: int): + def __init__(self, name: str, instrument: 'SR830', channel: int) -> None: """ Args: name (str): The name of the parameter From f222e18e3ef852c5ff97533d746af18250f625fb Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 25 Oct 2017 17:18:57 +0200 Subject: [PATCH 026/104] Annotate __init__ return --- qcodes/instrument/channel.py | 2 +- qcodes/instrument/parameter.py | 8 ++++---- qcodes/instrument_drivers/rohde_schwarz/RTO1000.py | 2 +- qcodes/instrument_drivers/rohde_schwarz/ZNB.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index 418e272a7c9..e0b0c3addca 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -27,7 +27,7 @@ class InstrumentChannel(InstrumentBase): channel. Usually populated via ``add_function`` """ - def __init__(self, parent: Instrument, name: str, **kwargs): + def __init__(self, parent: Instrument, name: str, **kwargs) -> None: # Initialize base classes of Instrument. We will overwrite what we # want to do in the Instrument initializer super().__init__(name=name, **kwargs) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 5d33e04ad4d..b75c06437c6 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -162,7 +162,7 @@ def __init__(self, name: str, snapshot_value: bool=True, max_val_age: Optional[float]=None, vals: Optional[Validator]=None, - delay: Optional[Union[int, float]]=None): + delay: Optional[Union[int, float]]=None) -> None: super().__init__(metadata) self.name = str(name) self._instrument = instrument @@ -730,7 +730,7 @@ def __init__(self, name: str, max_val_age: Optional[float]=None, vals: Optional[str]=None, docstring: Optional[str]=None, - **kwargs): + **kwargs) -> None: super().__init__(name=name, instrument=instrument, vals=vals, **kwargs) # Enable set/get methods if get_cmd/set_cmd is given @@ -907,7 +907,7 @@ def __init__(self, docstring: Optional[str]=None, snapshot_get: bool=True, snapshot_value: bool=False, - metadata: bool=None): + metadata: bool=None) -> None: super().__init__(name, instrument, snapshot_get, metadata, snapshot_value=snapshot_value) @@ -1083,7 +1083,7 @@ def __init__(self, docstring: str=None, snapshot_get: bool=True, snapshot_value: bool=False, - metadata: Optional[dict]=None): + metadata: Optional[dict]=None) -> None: super().__init__(name, instrument, snapshot_get, metadata, snapshot_value=snapshot_value) diff --git a/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py b/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py index 7f234331f15..525a9108f2b 100644 --- a/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py +++ b/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py @@ -287,7 +287,7 @@ def __init__(self, name: str, address: str, model: str=None, timeout: float=5., HD: bool=True, terminator: str='\n', - **kwargs): + **kwargs) -> None: """ Args: name: name of the instrument diff --git a/qcodes/instrument_drivers/rohde_schwarz/ZNB.py b/qcodes/instrument_drivers/rohde_schwarz/ZNB.py index 6369e362902..27ceb971d34 100644 --- a/qcodes/instrument_drivers/rohde_schwarz/ZNB.py +++ b/qcodes/instrument_drivers/rohde_schwarz/ZNB.py @@ -361,7 +361,7 @@ class ZNB(VisaInstrument): TODO: - check initialisation settings and test functions """ - def __init__(self, name: str, address: str, init_s_params: bool=True, **kwargs): + def __init__(self, name: str, address: str, init_s_params: bool=True, **kwargs) -> None: super().__init__(name=name, address=address, **kwargs) From bc6f50442988c4d3a3a7f2e66037dbb7fbe171dd Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 25 Oct 2017 17:19:21 +0200 Subject: [PATCH 027/104] make code easier to read by not reuseing variable name --- qcodes/monitor/monitor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 43ed7615cff..6d028bc8076 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -59,11 +59,11 @@ def _get_metadata(*parameters) -> Dict[float, list]: accumulator = metas.get(str(baseinst), []) accumulator.append(meta) metas[str(baseinst)] = accumulator - parameters = [] + parameters_out = [] for instrument in metas: temp = {"instrument": instrument, "parameters": metas[instrument]} - parameters.append(temp) - state = {"ts": ts, "parameters": parameters} + parameters_out.append(temp) + state = {"ts": ts, "parameters": parameters_out} return state From 1fc17a9ca0ab08f90562b70ca6ba8e425a21b627 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 25 Oct 2017 20:59:42 +0200 Subject: [PATCH 028/104] Correct type in ka driver --- qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py b/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py index a1654ea5b5d..eb00573be4f 100644 --- a/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py +++ b/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py @@ -1,5 +1,6 @@ from functools import partial import logging +from typing import Union from qcodes import VisaInstrument, validators as vals from qcodes.instrument.channel import InstrumentChannel @@ -27,7 +28,7 @@ def __init__(self, parent: Instrument, name: str, channum: int) -> None: """ super().__init__(parent, name) - def val_parser(parser: type, inputstring: str) -> str: + def val_parser(parser: type, inputstring: str) -> Union[float,int]: """ Parses return values from instrument. Meant to be used when a query can return a meaningful finite number or a numeric representation From 0eb85951556b9a474478038c7be3fb250bf4e7ce Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 25 Oct 2017 21:00:14 +0200 Subject: [PATCH 029/104] Better typing of parameter --- qcodes/instrument/parameter.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index b75c06437c6..b230cd6dbce 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -57,7 +57,7 @@ import os import collections import warnings -from typing import Optional, Sequence, TYPE_CHECKING, Union, Callable, List +from typing import Optional, Sequence, TYPE_CHECKING, Union, Callable, List, Dict, Any, Sized from functools import partial, wraps import numpy @@ -251,7 +251,7 @@ def __call__(self, *args, **kwargs): ' Parameter {}'.format(self.name)) def snapshot_base(self, update: bool=False, - params_to_skip_update: Sequence[str]=None) -> dict: + params_to_skip_update: Sequence[str]=None) -> Dict[str, Any]: """ State of the parameter as a JSON-compatible dict. @@ -416,7 +416,7 @@ def set_wrapper(value, **kwargs): return set_wrapper - def get_ramp_values(self, value: Union[float, int], + def get_ramp_values(self, value: Union[float, int, Sized], step: Union[float, int]=None) -> List[Union[float, int]]: """ @@ -728,7 +728,7 @@ def __init__(self, name: str, set_cmd: Optional[Union[str, Callable, bool]]=False, initial_value: Optional[Union[float, int, str]]=None, max_val_age: Optional[float]=None, - vals: Optional[str]=None, + vals: Optional[Validator]=None, docstring: Optional[str]=None, **kwargs) -> None: super().__init__(name=name, instrument=instrument, vals=vals, **kwargs) From 1539295d9caf65c7936fb31bb71c287eb894381d Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 25 Oct 2017 21:00:32 +0200 Subject: [PATCH 030/104] Improve typing of monitor --- qcodes/monitor/monitor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 6d028bc8076..da34834e088 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -20,7 +20,7 @@ import webbrowser from threading import Thread -from typing import Dict +from typing import Dict, Any from concurrent.futures import Future from concurrent.futures import CancelledError import functools @@ -32,14 +32,14 @@ log = logging.getLogger(__name__) -def _get_metadata(*parameters) -> Dict[float, list]: +def _get_metadata(*parameters) -> Dict[str, Any]: """ Return a dict that contains the parameter metadata grouped by the instrument it belongs to. """ ts = time.time() # group meta data by instrument if any - metas = {} + metas = {} # type: Dict for parameter in parameters: _meta = getattr(parameter, "_latest", None) if _meta: From e0595c35fac1edb685b0ca49c1ab1e5acda51732 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 25 Oct 2017 21:13:57 +0200 Subject: [PATCH 031/104] Improve channel typing --- qcodes/instrument/channel.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index e0b0c3addca..79e32ab75c0 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -1,5 +1,5 @@ """ Base class for the channel of an instrument """ -from typing import List, Tuple, Union, Optional +from typing import List, Tuple, Union, Optional, Dict, Sequence from .base import InstrumentBase, Instrument from .parameter import MultiParameter, ArrayParameter @@ -147,7 +147,7 @@ class ChannelList(Metadatable): def __init__(self, parent: Instrument, name: str, chan_type: type, - chan_list: Union[List, Tuple, None]=None, + chan_list: Union[List[InstrumentChannel], Tuple[InstrumentChannel, ...], None]=None, snapshotable: bool=True, multichan_paramclass: type = MultiChannelInstrumentParameter) -> None: super().__init__() @@ -168,13 +168,13 @@ def __init__(self, parent: Instrument, self._snapshotable = snapshotable self._paramclass = multichan_paramclass - self._channel_mapping = {} # provide lookup of channels by name + self._channel_mapping = {} # type: Dict[str, InstrumentChannel] + # provide lookup of channels by name # If a list of channels is not provided, define a list to store # channels. This will eventually become a locked tuple. if chan_list is None: self._locked = False - self._channels = [] # type: Union[List[InstrumentChannel],Tuple[InstrumentChannel], Tuple[InstrumentChannel, ...]] - # No idea why the last type is needed should never happen + self._channels = [] # type: Union[List[InstrumentChannel],Tuple[InstrumentChannel, ...]] else: self._locked = True self._channels = tuple(chan_list) @@ -236,7 +236,7 @@ def __add__(self, other: 'ChannelList'): "together.") return ChannelList(self._parent, self._name, self._chan_type, - self._channels + other._channels) + list(self._channels) + list(other._channels)) def append(self, obj: InstrumentChannel): """ @@ -313,7 +313,7 @@ def lock(self): self._channels = tuple(self._channels) self._locked = True - def snapshot_base(self, update: bool=False): + def snapshot_base(self, update: bool=False, params_to_skip_update: Optional[Sequence[str]]=None): """ State of the instrument as a JSON-compatible dict. From d34dc3fd3bffd116e90c4660974893e443baeab9 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Thu, 26 Oct 2017 10:42:11 +0200 Subject: [PATCH 032/104] type config --- qcodes/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/__init__.py b/qcodes/__init__.py index cfa0e3f04a6..61018ba594d 100644 --- a/qcodes/__init__.py +++ b/qcodes/__init__.py @@ -6,7 +6,7 @@ from qcodes.config import Config -config = Config() +config = Config() # type: Config from qcodes.version import __version__ From d556e0688afe4c3cd868b1f101cc0bce7797bbe8 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Thu, 26 Oct 2017 10:42:49 +0200 Subject: [PATCH 033/104] improve typing of dics --- qcodes/instrument/parameter.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index b230cd6dbce..2013ee3fb9c 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -269,7 +269,7 @@ def snapshot_base(self, update: bool=False, and self._snapshot_value and update: self.get() - state = copy(self._latest) + state = copy(self._latest) # type: Dict[str, Any] state['__class__'] = full_class(self) state['full_name'] = str(self) @@ -278,7 +278,8 @@ def snapshot_base(self, update: bool=False, state.pop('raw_value', None) if isinstance(state['ts'], datetime): - state['ts'] = state['ts'].strftime('%Y-%m-%d %H:%M:%S') + dttime = state['ts'] # type: datetime + state['ts'] = dttime.strftime('%Y-%m-%d %H:%M:%S') for attr in set(self._meta_attrs): if attr == 'instrument' and self._instrument: @@ -907,7 +908,7 @@ def __init__(self, docstring: Optional[str]=None, snapshot_get: bool=True, snapshot_value: bool=False, - metadata: bool=None) -> None: + metadata: Optional[dict]=None) -> None: super().__init__(name, instrument, snapshot_get, metadata, snapshot_value=snapshot_value) From 5e9e750244c7b27a4b093f0ea239137d87e4bc1a Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Thu, 26 Oct 2017 10:44:53 +0200 Subject: [PATCH 034/104] Try to improve typing of pyqtgraph module --- qcodes/plots/pyqtgraph.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/qcodes/plots/pyqtgraph.py b/qcodes/plots/pyqtgraph.py index 7512a4ba0c6..a4336260e0c 100644 --- a/qcodes/plots/pyqtgraph.py +++ b/qcodes/plots/pyqtgraph.py @@ -1,11 +1,12 @@ """ Live plotting using pyqtgraph """ -from typing import Optional, Dict, Union +from typing import Optional, Dict, Union, Deque, List import numpy as np import pyqtgraph as pg import pyqtgraph.multiprocess as pgmp from pyqtgraph.multiprocess.remoteproxy import ClosedError +from pyqtgraph.graphicsItems.PlotItem.PlotItem import PlotItem import qcodes.utils.helpers import warnings @@ -49,7 +50,8 @@ class QtPlot(BasePlot): # close event on win but this is difficult with remote proxy process # as the list of plots lives in the main process and the plot locally # in a remote process - plots = deque(maxlen=qcodes.config['gui']['pyqtmaxplots']) + max_len = qcodes.config['gui']['pyqtmaxplots'] # type: int + plots = deque(maxlen=max_len) # type: Deque['QtPlot'] def __init__(self, *args, figsize=(1000, 600), interval=0.25, window_title='', theme=((60, 60, 60), 'w'), show_window=True, remote=True, **kwargs): @@ -82,7 +84,7 @@ def __init__(self, *args, figsize=(1000, 600), interval=0.25, self.win.setBackground(theme[1]) self.win.resize(*figsize) self._orig_fig_size = figsize - self.subplots = [self.add_subplot()] + self.subplots = [self.add_subplot()] # type: List[PlotItem] if args or kwargs: self.add(*args, **kwargs) @@ -479,7 +481,7 @@ def setGeometry(self, x, y, w, h): """ Set geometry of the plotting window """ self.win.setGeometry(x, y, w, h) - def autorange(self, reset_colorbar: bool=False): + def autorange(self, reset_colorbar: bool=False) -> None: """ Auto range all limits in case they were changed during interactive plot. Reset colormap if changed and resize window to original size. @@ -487,7 +489,8 @@ def autorange(self, reset_colorbar: bool=False): reset_colorbar: Should the limits and colorscale of the colorbar be reset. Off by default """ - for subplot in self.subplots: + subplotss = self.subplots # type: List[PlotItem] + for subplot in subplotss: vBox = subplot.getViewBox() vBox.enableAutoRange(vBox.XYAxes) cmap = None From ab4e8f24a721bc80f031f1cba8148ba423976e13 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Thu, 26 Oct 2017 11:01:19 +0200 Subject: [PATCH 035/104] According to the docs __dir__ may return any sequence so cast it to a list --- qcodes/instrument/channel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index 79e32ab75c0..9dff74352bf 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -416,7 +416,7 @@ def multi_func(*args, **kwargs): ''.format(self.__class__.__name__, name)) def __dir__(self) -> list: - names = super().__dir__() + names = list(super().__dir__()) if self._channels: names += list(self._channels[0].parameters.keys()) names += list(self._channels[0].functions.keys()) From faaaf5769667b9377ef23d9f5c10fe315e62c7d0 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Thu, 26 Oct 2017 11:04:27 +0200 Subject: [PATCH 036/104] Explicitly check for tuple to help type inference --- qcodes/instrument/channel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index 9dff74352bf..026aa44837c 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -246,7 +246,7 @@ def append(self, obj: InstrumentChannel): Args: obj(chan_type): New channel to add to the list. """ - if self._locked: + if (isinstance(self._channels, tuple) or self._locked): raise AttributeError("Cannot append to a locked channel list") if not isinstance(obj, self._chan_type): raise TypeError("All items in a channel list must be of the same " @@ -292,7 +292,7 @@ def insert(self, index: int, obj: InstrumentChannel): obj(chan_type): Object of type chan_type to insert. """ - if self._locked: + if (isinstance(self._channels, tuple) or self._locked): raise AttributeError("Cannot insert into a locked channel list") if not isinstance(obj, self._chan_type): raise TypeError("All items in a channel list must be of the same " From c799e97bbae9f5252a403926e45e2cc048599b95 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Thu, 26 Oct 2017 11:17:18 +0200 Subject: [PATCH 037/104] remove workaround --- qcodes/data/location.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/qcodes/data/location.py b/qcodes/data/location.py index 7db1071913b..92555307ed1 100644 --- a/qcodes/data/location.py +++ b/qcodes/data/location.py @@ -3,7 +3,7 @@ import re import string -from qcodes import config +import qcodes.config class SafeFormatter(string.Formatter): @@ -83,9 +83,7 @@ class FormatLocation: as '{date:%Y-%m-%d}' or '{counter:03}' """ - default_fmt = config['core']['default_fmt'] # type: ignore - # silence warning about the type of config, not sure how to do this - # correctly + default_fmt = qcodes.config['core']['default_fmt'] def __init__(self, fmt=None, fmt_date=None, fmt_time=None, fmt_counter=None, record=None): From 0feec63e805ada39784fd0b54d5755173a088077 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Thu, 26 Oct 2017 11:24:23 +0200 Subject: [PATCH 038/104] simplify typing --- qcodes/instrument/channel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index 026aa44837c..3afb05dd92c 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -147,7 +147,7 @@ class ChannelList(Metadatable): def __init__(self, parent: Instrument, name: str, chan_type: type, - chan_list: Union[List[InstrumentChannel], Tuple[InstrumentChannel, ...], None]=None, + chan_list: Optional[Sequence[InstrumentChannel]]=None, snapshotable: bool=True, multichan_paramclass: type = MultiChannelInstrumentParameter) -> None: super().__init__() From 86d31dae6794f40d2e57e422326a57fbf7193fdc Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Thu, 26 Oct 2017 11:24:52 +0200 Subject: [PATCH 039/104] still trying to get the type of self.subplots correct --- qcodes/plots/pyqtgraph.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/plots/pyqtgraph.py b/qcodes/plots/pyqtgraph.py index a4336260e0c..4606de0a7f5 100644 --- a/qcodes/plots/pyqtgraph.py +++ b/qcodes/plots/pyqtgraph.py @@ -111,7 +111,7 @@ def clear(self): """ self.win.clear() self.traces = [] - self.subplots = [] + self.subplots = [] # type: List[PlotItem] def add_subplot(self): subplot_object = self.win.addPlot() @@ -489,8 +489,8 @@ def autorange(self, reset_colorbar: bool=False) -> None: reset_colorbar: Should the limits and colorscale of the colorbar be reset. Off by default """ - subplotss = self.subplots # type: List[PlotItem] - for subplot in subplotss: + subplots = self.subplots # type: List[PlotItem] + for subplot in subplots: vBox = subplot.getViewBox() vBox.enableAutoRange(vBox.XYAxes) cmap = None From 593904d8136539f5e25eed9855b702e2c0d5edf2 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 27 Oct 2017 11:15:20 +0200 Subject: [PATCH 040/104] Type fixes and workarounds to parameter --- qcodes/instrument/parameter.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 2013ee3fb9c..47c82c8abc6 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -202,14 +202,16 @@ def __init__(self, name: str, self.get_latest = GetLatest(self, max_val_age=max_val_age) if hasattr(self, 'get_raw'): - self.get = self._wrap_get(self.get_raw) + self.get = self._wrap_get(self.get_raw) # type: ignore + # due to https://github.com/python/mypy/issues/1424 elif hasattr(self, 'get'): warnings.warn('Wrapping get method, original get method will not ' 'be directly accessible. It is recommended to ' 'define get_raw in your subclass instead.' ) self.get = self._wrap_get(self.get) if hasattr(self, 'set_raw'): - self.set = self._wrap_set(self.set_raw) + self.set = self._wrap_set(self.set_raw) # type: ignore + # due to https://github.com/python/mypy/issues/1424 elif hasattr(self, 'set'): warnings.warn('Wrapping set method, original set method will not ' 'be directly accessible. It is recommended to ' @@ -419,7 +421,8 @@ def set_wrapper(value, **kwargs): def get_ramp_values(self, value: Union[float, int, Sized], step: Union[float, int]=None) -> List[Union[float, - int]]: + int, + Sized]]: """ Return values to sweep from current value to target value. This method can be overridden to have a custom sweep behaviour. @@ -434,7 +437,7 @@ def get_ramp_values(self, value: Union[float, int, Sized], if step is None: return [value] else: - if isinstance(value, collections.Iterable) and len(value) > 1: + if isinstance(value, collections.Sized) and len(value) > 1: raise RuntimeError("Don't know how to step a parameter with more than one value") if self.get_latest() is None: self.get() From 3ba5c309a9a04bf9f61ef421036ddd0fde6e4df9 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 27 Oct 2017 11:33:05 +0200 Subject: [PATCH 041/104] last typing issue in parameter --- qcodes/instrument/parameter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 47c82c8abc6..72620c4f639 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -752,10 +752,10 @@ def __init__(self, name: str, if not hasattr(self, 'set') and set_cmd is not False: if set_cmd is None: - self.set_raw = partial(self._save_val, validate=False) + self.set_raw = partial(self._save_val, validate=False)# type: Callable else: exec_str = instrument.write if instrument else None - self.set_raw = Command(arg_count=1, cmd=set_cmd, exec_str=exec_str) + self.set_raw = Command(arg_count=1, cmd=set_cmd, exec_str=exec_str)# type: Callable self.set = self._wrap_set(self.set_raw) self._meta_attrs.extend(['label', 'unit', 'vals']) From c85b0935333c3031fbaaa668317fe541ae5a8810 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 27 Oct 2017 11:34:19 +0200 Subject: [PATCH 042/104] work around mypy bug in pyqtplot --- qcodes/plots/pyqtgraph.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/qcodes/plots/pyqtgraph.py b/qcodes/plots/pyqtgraph.py index 8d4d571deb9..8bfcfe2f6c6 100644 --- a/qcodes/plots/pyqtgraph.py +++ b/qcodes/plots/pyqtgraph.py @@ -1,11 +1,11 @@ """ Live plotting using pyqtgraph """ -from typing import Optional, Dict, Union, Deque, List +from typing import Optional, Dict, Union, Deque, List, cast import numpy as np import pyqtgraph as pg import pyqtgraph.multiprocess as pgmp -from pyqtgraph.multiprocess.remoteproxy import ClosedError +from pyqtgraph.multiprocess.remoteproxy import ClosedError, ObjectProxy from pyqtgraph.graphicsItems.PlotItem.PlotItem import PlotItem import qcodes.utils.helpers @@ -84,7 +84,7 @@ def __init__(self, *args, figsize=(1000, 600), interval=0.25, self.win.setBackground(theme[1]) self.win.resize(*figsize) self._orig_fig_size = figsize - self.subplots = [self.add_subplot()] # type: List[PlotItem] + self.subplots = [self.add_subplot()] # type: List[Union[PlotItem, ObjectProxy]] if args or kwargs: self.add(*args, **kwargs) @@ -111,7 +111,7 @@ def clear(self): """ self.win.clear() self.traces = [] - self.subplots = [] # type: List[PlotItem] + self.subplots = [] # type: List[Union[PlotItem, ObjectProxy]] def add_subplot(self): subplot_object = self.win.addPlot() @@ -489,7 +489,10 @@ def autorange(self, reset_colorbar: bool=False) -> None: reset_colorbar: Should the limits and colorscale of the colorbar be reset. Off by default """ - subplots = self.subplots # type: List[PlotItem] + # seem to be a bug in mypy but the type of self.subplots cannot be + # deducted even when typed above so ignore it and cast for now + subplots = self.subplots # type: ignore + subplots = cast(List[Union[PlotItem,ObjectProxy]], subplots) for subplot in subplots: vBox = subplot.getViewBox() vBox.enableAutoRange(vBox.XYAxes) @@ -526,7 +529,11 @@ def fixUnitScaling(self, startranges: Optional[Dict[str, Dict[str, Union[float,i axismapping = {'x': 'bottom', 'y': 'left'} standardunits = self.standardunits - for i, plot in enumerate(self.subplots): + # seem to be a bug in mypy but the type of self.subplots cannot be + # deducted even when typed above so ignore it and cast for now + subplots = self.subplots # type: ignore + subplots = cast(List[Union[PlotItem,ObjectProxy]], subplots) + for i, plot in enumerate(subplots): # make a dict mapping axis labels to axis positions for axis in ('x', 'y', 'z'): if self.traces[i]['config'].get(axis) is not None: From e3341dbad0a09f1fedc6c8a275119c2778029f54 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 27 Oct 2017 13:11:03 +0200 Subject: [PATCH 043/104] Better typing of CombinedParameter --- qcodes/instrument/parameter.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 72620c4f639..c9ca223202e 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -1296,7 +1296,7 @@ def set(self, index: int): setFunction(value) return values - def sweep(self, *array: numpy.ndarray): + def sweep(self, *array: numpy.ndarray) -> 'CombinedParameter': """ Creates a new combined parameter to be iterated over. One can sweep over either: @@ -1318,26 +1318,26 @@ def sweep(self, *array: numpy.ndarray): dim = set([len(a) for a in array]) if len(dim) != 1: raise ValueError('Arrays have different number of setpoints') - array = numpy.array(array).transpose() + nparray = numpy.array(array).transpose() else: # cast to array in case users # decide to not read docstring # and pass a 2d list - array = numpy.array(array[0]) + nparray = numpy.array(array[0]) new = copy(self) _error_msg = """ Dimensionality of array does not match\ the number of parameter combined. Expected a \ {} dimensional array, got a {} dimensional array. \ """ try: - if array.shape[1] != self.dimensionality: # type: ignore + if nparray.shape[1] != self.dimensionality: raise ValueError(_error_msg.format(self.dimensionality, - array.shape[1])) # type: ignore + nparray.shape[1])) except KeyError: # this means the array is 1d raise ValueError(_error_msg.format(self.dimensionality, 1)) - new.setpoints = array.tolist() # type: ignore + new.setpoints = nparray.tolist() return new def _aggregate(self, *vals): From bd3af1c5c6d46f44843f94b8cff19b1012715b80 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 27 Oct 2017 13:32:41 +0200 Subject: [PATCH 044/104] remove unused imports --- qcodes/config/config.py | 2 +- qcodes/instrument_drivers/Keysight/test_suite.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/qcodes/config/config.py b/qcodes/config/config.py index 9a0392acf0e..4d8518c25df 100644 --- a/qcodes/config/config.py +++ b/qcodes/config/config.py @@ -9,7 +9,7 @@ from pathlib import Path import jsonschema -from typing import Dict, Union +from typing import Dict logger = logging.getLogger(__name__) diff --git a/qcodes/instrument_drivers/Keysight/test_suite.py b/qcodes/instrument_drivers/Keysight/test_suite.py index bcd96d28ebd..cffc5f10a3f 100644 --- a/qcodes/instrument_drivers/Keysight/test_suite.py +++ b/qcodes/instrument_drivers/Keysight/test_suite.py @@ -1,6 +1,5 @@ from qcodes.instrument_drivers.test import DriverTestCase import unittest -from typing import Optional try: from .M3201A import Keysight_M3201A From fd682501bcde5eb91f0c19425677cb7bfecd6a33 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Mon, 30 Oct 2017 14:59:57 +0100 Subject: [PATCH 045/104] Improve typing of dict There does not seem to be a standard way to type an OrderedDict so do it witwith a regular dict --- qcodes/data/data_set.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/data/data_set.py b/qcodes/data/data_set.py index a7e19bc213e..b5c52b8c049 100644 --- a/qcodes/data/data_set.py +++ b/qcodes/data/data_set.py @@ -5,6 +5,7 @@ from traceback import format_exc from copy import deepcopy from collections import OrderedDict +from typing import Dict, Callable from .gnuplot_format import GNUPlotFormat from .io import DiskIO @@ -168,7 +169,7 @@ class DataSet(DelegateAttributes): default_formatter = GNUPlotFormat() location_provider = FormatLocation() - background_functions = OrderedDict() # type: OrderedDict + background_functions = OrderedDict() # type: Dict[str, Callable] def __init__(self, location=None, arrays=None, formatter=None, io=None, write_period=5): From 871429dc3248821bf69552179def237bdcf243a4 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 3 Nov 2017 17:43:53 +0100 Subject: [PATCH 046/104] better way of handling get/set raw --- qcodes/instrument/parameter.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 2f6797d67d9..e1c7932fa5f 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -57,7 +57,7 @@ import os import collections import warnings -from typing import Optional, Sequence, TYPE_CHECKING, Union, Callable, List, Dict, Any, Sized +from typing import Optional, Sequence, TYPE_CHECKING, Union, Callable, List, Dict, Any, Sized, cast from functools import partial, wraps import numpy @@ -147,6 +147,8 @@ class _BaseParameter(Metadatable, DeferredOperations): metadata (Optional[dict]): extra information to include with the JSON snapshot of the parameter """ + get_raw = None # type: Optional[Callable] + set_raw = None # type: Optional[Callable] def __init__(self, name: str, instrument: Optional['Instrument'], @@ -201,17 +203,15 @@ def __init__(self, name: str, self._latest = {'value': None, 'ts': None, 'raw_value': None} self.get_latest = GetLatest(self, max_val_age=max_val_age) - if hasattr(self, 'get_raw'): - self.get = self._wrap_get(self.get_raw) # type: ignore - # due to https://github.com/python/mypy/issues/1424 + if hasattr(self, 'get_raw') and self.get_raw is not None: + self.get = self._wrap_get(self.get_raw) elif hasattr(self, 'get'): warnings.warn('Wrapping get method, original get method will not ' 'be directly accessible. It is recommended to ' 'define get_raw in your subclass instead.' ) self.get = self._wrap_get(self.get) - if hasattr(self, 'set_raw'): - self.set = self._wrap_set(self.set_raw) # type: ignore - # due to https://github.com/python/mypy/issues/1424 + if hasattr(self, 'set_raw') and self.set_raw is not None: + self.set = self._wrap_set(self.set_raw) elif hasattr(self, 'set'): warnings.warn('Wrapping set method, original set method will not ' 'be directly accessible. It is recommended to ' From 43a4dd082e41480cb511d740dff4598ab28d2850 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 3 Nov 2017 17:44:19 +0100 Subject: [PATCH 047/104] dont leak unknow type --- qcodes/instrument_drivers/devices.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/devices.py b/qcodes/instrument_drivers/devices.py index deb765f194c..0544ea98c3b 100644 --- a/qcodes/instrument_drivers/devices.py +++ b/qcodes/instrument_drivers/devices.py @@ -1,4 +1,4 @@ -from typing import Union +from typing import Union, cast from qcodes import Parameter, Instrument @@ -75,6 +75,8 @@ def __init__(self, def set_raw(self, value: Union[int, float]) -> None: instrument_value = value * self.division_value # type: ignore # disable type check due to https://github.com/python/mypy/issues/2128 + instrument_value = cast(Union[int, float], instrument_value) + self._save_val(value) self.v1.set(instrument_value) From 3521441947b56808296dc8a62a0c2e70c98ece83 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Mon, 6 Nov 2017 17:48:30 +0100 Subject: [PATCH 048/104] type components to help linter --- qcodes/station.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/station.py b/qcodes/station.py index 7b6cd9a020b..d46f545d5a5 100644 --- a/qcodes/station.py +++ b/qcodes/station.py @@ -1,4 +1,5 @@ """Station objects - collect all the equipment you use to do an experiment.""" +from typing import Dict from qcodes.utils.metadata import Metadatable from qcodes.utils.helpers import make_unique, DelegateAttributes @@ -55,7 +56,7 @@ def __init__(self, *components, monitor=None, default=True, if default: Station.default = self - self.components = {} + self.components = {} # type: Dict[str, Instrument] for item in components: self.add_component(item, update_snapshot=update_snapshot) From 725368b595f0b0be4739d69a088c28f4a0d4b40f Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Mon, 6 Nov 2017 18:15:19 +0100 Subject: [PATCH 049/104] type station no attempt to type actions --- qcodes/station.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/qcodes/station.py b/qcodes/station.py index d46f545d5a5..56d6260f283 100644 --- a/qcodes/station.py +++ b/qcodes/station.py @@ -1,5 +1,5 @@ """Station objects - collect all the equipment you use to do an experiment.""" -from typing import Dict +from typing import Dict, List, Optional, Sequence, Any from qcodes.utils.metadata import Metadatable from qcodes.utils.helpers import make_unique, DelegateAttributes @@ -26,7 +26,7 @@ class Station(Metadatable, DelegateAttributes): *components (list[Any]): components to add immediately to the Station. can be added later via self.add_component - monitor (None): Not implememnted, the object that monitors the system continuously + monitor (None): Not implemented, the object that monitors the system continuously default (bool): is this station the default, which gets used in Loops and elsewhere that a Station can be specified, default true @@ -41,10 +41,11 @@ class Station(Metadatable, DelegateAttributes): attributes of self """ - default = None + default = None # type: 'Station' - def __init__(self, *components, monitor=None, default=True, - update_snapshot=True, **kwargs): + def __init__(self, *components: Metadatable, + monitor: Any, default: bool=True, + update_snapshot: bool=True, **kwargs) -> None: super().__init__(**kwargs) # when a new station is defined, store it in a class variable @@ -56,21 +57,22 @@ def __init__(self, *components, monitor=None, default=True, if default: Station.default = self - self.components = {} # type: Dict[str, Instrument] + self.components = {} # type: Dict[str, Metadatable] for item in components: self.add_component(item, update_snapshot=update_snapshot) self.monitor = monitor - self.default_measurement = [] + self.default_measurement = [] # type: List - def snapshot_base(self, update=False): + def snapshot_base(self, update: bool=False, + params_to_skip_update: Sequence[str]=None) -> Dict: """ State of the station as a JSON-compatible dict. Args: update (bool): If True, update the state by querying the - all the childs: f.ex. instruments, parameters, components, etc. + all the children: f.ex. instruments, parameters, components, etc. If False, just use the latest values in memory. Returns: @@ -97,7 +99,8 @@ def snapshot_base(self, update=False): return snap - def add_component(self, component, name=None, update_snapshot=True): + def add_component(self, component: Metadatable, name: str=None, + update_snapshot: bool=True) -> str: """ Record one component as part of this Station. From 58981136febfb8ca5663721e266fd9c0a3f61b40 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Mon, 13 Nov 2017 11:11:47 +0100 Subject: [PATCH 050/104] Monitor is optional --- qcodes/station.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/station.py b/qcodes/station.py index 56d6260f283..e0a06c77e09 100644 --- a/qcodes/station.py +++ b/qcodes/station.py @@ -44,7 +44,7 @@ class Station(Metadatable, DelegateAttributes): default = None # type: 'Station' def __init__(self, *components: Metadatable, - monitor: Any, default: bool=True, + monitor: Any=None, default: bool=True, update_snapshot: bool=True, **kwargs) -> None: super().__init__(**kwargs) From 260fcc3dfe6d8a3b39c73a8ffb27473216d1cddc Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Tue, 14 Nov 2017 10:19:55 +0100 Subject: [PATCH 051/104] no longer need to exclude deleted file --- docs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile b/docs/Makefile index 33174254824..0e8e2034639 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -229,7 +229,7 @@ dummy: @echo "Build finished. Dummy builder generates no files." html-api: - sphinx-apidoc -o _auto -d 10 ../qcodes/ ../qcodes/instrument_drivers/Spectrum/pyspcm.py ../qcodes/instrument_drivers/Spectrum/py_header/h2py.py + sphinx-apidoc -o _auto -d 10 ../qcodes/ ../qcodes/instrument_drivers/Spectrum/pyspcm.py mkdir -p api/generated/ mkdir -p _notebooks mkdir -p _notebooks/driver_examples From 4b5387b209c10abf2e200b87c4c08d66cab9c9ad Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Tue, 14 Nov 2017 16:24:51 +0100 Subject: [PATCH 052/104] dont change pyspcm --- qcodes/instrument_drivers/Spectrum/pyspcm.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/Spectrum/pyspcm.py b/qcodes/instrument_drivers/Spectrum/pyspcm.py index 11bbe19b06c..b278ca7d1fb 100644 --- a/qcodes/instrument_drivers/Spectrum/pyspcm.py +++ b/qcodes/instrument_drivers/Spectrum/pyspcm.py @@ -1,7 +1,6 @@ import os import platform -import sys -from ctypes import c_int8, c_int16, c_int32,c_int64, POINTER, c_uint8, c_uint16, c_uint32, c_uint64, c_void_p, windll, cdll, c_char_p +import sys from ctypes import * # load registers for easier access From a8b6334f3dc249f2540c38b9eb80c806bb7e0542 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 15 Nov 2017 10:11:27 +0100 Subject: [PATCH 053/104] Import instrument from full path --- qcodes/instrument_drivers/QuTech/D4.py | 4 +--- qcodes/instrument_drivers/QuTech/D5a.py | 2 +- qcodes/instrument_drivers/QuTech/F1d.py | 2 +- qcodes/instrument_drivers/QuTech/S5i.py | 2 +- qcodes/instrument_drivers/stanford_research/SR560.py | 2 +- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/qcodes/instrument_drivers/QuTech/D4.py b/qcodes/instrument_drivers/QuTech/D4.py index 7072f0682ec..262c87134a0 100644 --- a/qcodes/instrument_drivers/QuTech/D4.py +++ b/qcodes/instrument_drivers/QuTech/D4.py @@ -1,5 +1,4 @@ -from qcodes import Instrument - +from qcodes.instrument.base import Instrument try: from spirack import D4_module except ImportError: @@ -8,7 +7,6 @@ from functools import partial - class D4(Instrument): """ Qcodes driver for the D4 ADC SPI-rack module. Requires installation diff --git a/qcodes/instrument_drivers/QuTech/D5a.py b/qcodes/instrument_drivers/QuTech/D5a.py index b12af6eec45..7dcf3fae5e3 100644 --- a/qcodes/instrument_drivers/QuTech/D5a.py +++ b/qcodes/instrument_drivers/QuTech/D5a.py @@ -1,4 +1,4 @@ -from qcodes import Instrument +from qcodes.instrument.base import Instrument from qcodes.utils.validators import Enum, Numbers try: diff --git a/qcodes/instrument_drivers/QuTech/F1d.py b/qcodes/instrument_drivers/QuTech/F1d.py index 07364b0e2be..4095334ccd2 100644 --- a/qcodes/instrument_drivers/QuTech/F1d.py +++ b/qcodes/instrument_drivers/QuTech/F1d.py @@ -1,4 +1,4 @@ -from qcodes import Instrument +from qcodes.instrument.base import Instrument from qcodes.utils.validators import Enum try: diff --git a/qcodes/instrument_drivers/QuTech/S5i.py b/qcodes/instrument_drivers/QuTech/S5i.py index e324e0d0411..163b6dd808e 100644 --- a/qcodes/instrument_drivers/QuTech/S5i.py +++ b/qcodes/instrument_drivers/QuTech/S5i.py @@ -1,4 +1,4 @@ -from qcodes import Instrument +from qcodes.instrument.base import Instrument from qcodes.utils.validators import Bool, Numbers try: diff --git a/qcodes/instrument_drivers/stanford_research/SR560.py b/qcodes/instrument_drivers/stanford_research/SR560.py index 1fb9f03b3f2..b961859d71a 100644 --- a/qcodes/instrument_drivers/stanford_research/SR560.py +++ b/qcodes/instrument_drivers/stanford_research/SR560.py @@ -1,4 +1,4 @@ -from qcodes import Instrument +from qcodes.instrument.base import Instrument from qcodes.instrument.parameter import MultiParameter from qcodes.utils.validators import Bool, Enum From c14da1d23446cc16cd82bef487b2b4659956dd29 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 15 Nov 2017 10:11:39 +0100 Subject: [PATCH 054/104] no longer needed --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 17c0f1710b0..6b3110eb0ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,7 @@ script: - py.test --cov=qcodes --cov-report xml --cov-config=.coveragerc - | cd .. - mypy qcodes --ignore-missing-imports --follow-imports=skip + mypy qcodes --ignore-missing-imports - | cd docs make html-api From d0056d68c8098206332cac562c73241c0b42978e Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 15 Nov 2017 10:20:51 +0100 Subject: [PATCH 055/104] missed one --- qcodes/instrument_drivers/ithaco/Ithaco_1211.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/ithaco/Ithaco_1211.py b/qcodes/instrument_drivers/ithaco/Ithaco_1211.py index 709a537b12c..83694539e6f 100644 --- a/qcodes/instrument_drivers/ithaco/Ithaco_1211.py +++ b/qcodes/instrument_drivers/ithaco/Ithaco_1211.py @@ -1,4 +1,4 @@ -from qcodes import Instrument +from qcodes.instrument.base import Instrument from qcodes.instrument.parameter import MultiParameter from qcodes.utils.validators import Enum, Bool From 33f28d5dec2b00531cf609c5392a0a50e9749b50 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 15 Nov 2017 10:33:37 +0100 Subject: [PATCH 056/104] correct argument to logging --- qcodes/instrument_drivers/Spectrum/M4i.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/instrument_drivers/Spectrum/M4i.py b/qcodes/instrument_drivers/Spectrum/M4i.py index 58b7d10497b..782d51ce3a5 100644 --- a/qcodes/instrument_drivers/Spectrum/M4i.py +++ b/qcodes/instrument_drivers/Spectrum/M4i.py @@ -31,9 +31,9 @@ sys.path.append(header_dir) import pyspcm except (ImportError, OSError) as ex: - log.exception(ex) - raise ImportError( - 'to use the M4i driver install the pyspcm module and the M4i libs') + info_str = 'to use the M4i driver install the pyspcm module and the M4i libs' + log.exception(info_str) + raise ImportError(info_str) #%% Helper functions From 1930d8fc85803b3ca08a122fb98c0e7f63d2b144 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 15 Nov 2017 10:34:04 +0100 Subject: [PATCH 057/104] minimal changes to get pyspcm running with mypy --- qcodes/instrument_drivers/Spectrum/pyspcm.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qcodes/instrument_drivers/Spectrum/pyspcm.py b/qcodes/instrument_drivers/Spectrum/pyspcm.py index b278ca7d1fb..5d47b396d5c 100644 --- a/qcodes/instrument_drivers/Spectrum/pyspcm.py +++ b/qcodes/instrument_drivers/Spectrum/pyspcm.py @@ -1,6 +1,7 @@ import os import platform -import sys +import sys +from ctypes import c_int8, c_int16, c_int32, c_int64, c_uint8, c_uint16, c_uint32, c_uint64, c_char_p, POINTER, c_void_p, cdll from ctypes import * # load registers for easier access @@ -59,9 +60,9 @@ # Load DLL into memory. # use windll because all driver access functions use _stdcall calling convention under windows if (bIs64Bit == 1): - spcmDll = windll.LoadLibrary ("c:\\windows\\system32\\spcm_win64.dll") + spcmDll = windll.LoadLibrary ("c:\\windows\\system32\\spcm_win64.dll") # type: ignore else: - spcmDll = windll.LoadLibrary ("c:\\windows\\system32\\spcm_win32.dll") + spcmDll = windll.LoadLibrary ("c:\\windows\\system32\\spcm_win32.dll") # type: ignore # load spcm_hOpen if (bIs64Bit): From 509a517d20b5a1f3f86d1f9273017978d6ce849a Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Mon, 27 Nov 2017 15:12:06 +0100 Subject: [PATCH 058/104] fix typeing for ZI driver --- qcodes/instrument_drivers/ZI/ZIUHFLI.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIUHFLI.py b/qcodes/instrument_drivers/ZI/ZIUHFLI.py index 93ef0e6cb67..2e274f5916a 100644 --- a/qcodes/instrument_drivers/ZI/ZIUHFLI.py +++ b/qcodes/instrument_drivers/ZI/ZIUHFLI.py @@ -3,7 +3,7 @@ import numpy as np from functools import partial -from typing import Callable, List, Union +from typing import Callable, List, Union, cast try: import zhinst.utils @@ -1242,7 +1242,7 @@ def __init__(self, name: str, device_ID: str, **kwargs) -> None: # A "manual" parameter: a list of the signals for the sweeper # to subscribe to - self._sweeper_signals = [] + self._sweeper_signals = [] # type: List[str] # This is the dictionary keeping track of the sweeper settings # These are the default settings @@ -1628,7 +1628,7 @@ def _get_demod_sample(self, number: int, demod_param: str) -> float: setting = 'sample' if demod_param not in ['x', 'y', 'R', 'phi']: raise RuntimeError("Invalid demodulator parameter") - datadict = self._getter(module, number, mode, setting) + datadict = cast(dict, self._getter(module, number, mode, setting)) datadict['R'] = np.abs(datadict['x'] + 1j * datadict['y']) datadict['phi'] = np.angle(datadict['x'] + 1j * datadict['y'], deg=True) return datadict[demod_param] From fe4c9a3681829eff2ac73c055dfcb28ae1151652 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Mon, 4 Dec 2017 10:13:40 +0100 Subject: [PATCH 059/104] Fix type annotation in gs200 This uncovered atleast on real bug as *kwargs should be **kwargs --- qcodes/instrument_drivers/yokogawa/GS200.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/qcodes/instrument_drivers/yokogawa/GS200.py b/qcodes/instrument_drivers/yokogawa/GS200.py index 7caa91d46f3..f3896ebe2cc 100644 --- a/qcodes/instrument_drivers/yokogawa/GS200.py +++ b/qcodes/instrument_drivers/yokogawa/GS200.py @@ -1,4 +1,5 @@ from functools import partial +from typing import Optional from qcodes import VisaInstrument, InstrumentChannel from qcodes.utils.validators import Numbers, Bool, Enum, Ints @@ -34,7 +35,7 @@ class GS200_Monitor(InstrumentChannel): name (str): instrument name present (bool): """ - def __init__(self, parent: 'GS200', name: str, present: bool): + def __init__(self, parent: 'GS200', name: str, present: bool) -> None: super().__init__(parent, name) self.present = present @@ -167,8 +168,9 @@ class GS200(VisaInstrument): terminator (str): read terminator for reads/writes to the instrument. """ - def __init__(self, name: str, address: str, terminator: str="\n", **kwargs): - super().__init__(name, address, terminator=terminator, *kwargs) + def __init__(self, name: str, address: str, terminator: str="\n", + **kwargs) -> None: + super().__init__(name, address, terminator=terminator, **kwargs) self.add_parameter('output', label='Output State', @@ -193,7 +195,7 @@ def __init__(self, name: str, address: str, terminator: str="\n", **kwargs): # We want to cache the range value so communication with the instrument only happens when the set the # range. Getting the range always returns the cached value. This value is adjusted when calling # self._set_range - self._cached_range_value = None + self._cached_range_value = None # type: Optional[float] self.add_parameter('voltage_range', label='Voltage Source Range', @@ -353,7 +355,8 @@ def _ramp_source(self, ramp_to: float, step: float, delay: float) -> None: self.output_level.step = saved_step self.output_level.inter_delay = saved_inter_delay - def _get_set_output(self, mode: str, output_level: float=None) -> float: + def _get_set_output(self, mode: str, + output_level: float=None) -> Optional[float]: """ Get or set the output level. @@ -364,6 +367,7 @@ def _get_set_output(self, mode: str, output_level: float=None) -> float: self._assert_mode(mode) if output_level is not None: self._set_output(output_level) + return None else: return float(self.ask(":SOUR:LEV?")) From f2fbf9a47971a10924807933aba97d412283a92c Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Mon, 4 Dec 2017 10:19:57 +0100 Subject: [PATCH 060/104] Add missing return statment --- qcodes/instrument/channel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index 598168e4243..a714d244c84 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -446,7 +446,7 @@ class ChannelListValidator(Validator): The channel list must be locked and populated before it can be used to construct a validator. """ - def __init__(self, channel_list: ChannelList): + def __init__(self, channel_list: ChannelList) -> None: # Save the base parameter list if not isinstance(channel_list, ChannelList): raise ValueError("channel_list must be a ChannelList object containing the " From e27ac1764de934d2904d767499bcb6160e20bb3d Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Mon, 4 Dec 2017 10:20:18 +0100 Subject: [PATCH 061/104] remove unused attribute --- qcodes/instrument_drivers/stanford_research/SR86x.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/stanford_research/SR86x.py b/qcodes/instrument_drivers/stanford_research/SR86x.py index 4e2ed9e22c6..75509f77660 100644 --- a/qcodes/instrument_drivers/stanford_research/SR86x.py +++ b/qcodes/instrument_drivers/stanford_research/SR86x.py @@ -1,6 +1,7 @@ import numpy as np import time import logging +from typing import Optional from qcodes import VisaInstrument from qcodes.instrument.channel import InstrumentChannel @@ -140,7 +141,6 @@ def __init__(self, parent: 'SR86x', name: str) ->None: ) self.bytes_per_sample = 4 - self._capture_data = dict() @staticmethod def _set_capture_len_parser(value: int) -> int: From c7f0f71e7ae2e8777e1c112aa5e4e4520d448517 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 6 Dec 2017 13:10:26 +0100 Subject: [PATCH 062/104] more type annotations --- qcodes/instrument/base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index 8ef94c6b637..d74ff0f02bd 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -12,7 +12,7 @@ from qcodes.utils.helpers import DelegateAttributes, strip_attrs, full_class from qcodes.utils.metadata import Metadatable from qcodes.utils.validators import Anything -from .parameter import Parameter +from .parameter import Parameter, _BaseParameter from .function import Function log = logging.getLogger(__name__) @@ -47,9 +47,9 @@ def __init__(self, name: str, metadata: Optional[Dict]=None, **kwargs) -> None: self.name = str(name) - self.parameters = {} - self.functions = {} - self.submodules = {} + self.parameters = {} # type: Dict[str, _BaseParameter] + self.functions = {} # type: Dict[str, Function] + self.submodules = {} # type: Dict[str, Metadatable] super().__init__(**kwargs) def add_parameter(self, name: str, From defd2e63fdbad6a78df6eae9375acaf2c1713b59 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Tue, 12 Dec 2017 16:25:28 +0100 Subject: [PATCH 063/104] no longer need to change dir here --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 902377bd8c3..05b89d7574d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,7 @@ script: cd .. mypy qcodes --ignore-missing-imports - | - cd ../docs + cd docs make SPHINXOPTS="-W" html-api - cd .. From e7a7fa3825b4dff00eec5498fb51126e52c0d23b Mon Sep 17 00:00:00 2001 From: Jens H Nielsen Date: Thu, 14 Dec 2017 10:13:45 +0100 Subject: [PATCH 064/104] fix typing of awg import time from the original location and dont overwrite variable --- qcodes/instrument_drivers/tektronix/AWG70000A.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG70000A.py b/qcodes/instrument_drivers/tektronix/AWG70000A.py index 043743e4b59..b1089e0a0cd 100644 --- a/qcodes/instrument_drivers/tektronix/AWG70000A.py +++ b/qcodes/instrument_drivers/tektronix/AWG70000A.py @@ -6,7 +6,7 @@ import zipfile as zf import logging -from dateutil.tz import time +import time from typing import List, Sequence from qcodes import Instrument, VisaInstrument, validators as vals @@ -336,10 +336,10 @@ def waveformList(self) -> List[str]: """ Return the waveform list as a list of strings """ - resp = self.ask("WLISt:LIST?") - resp = resp.strip() - resp = resp.replace('"', '') - resp = resp.split(',') + respstr = self.ask("WLISt:LIST?") + respstr = respstr.strip() + respstr = respstr.replace('"', '') + resp = respstr.split(',') return resp From b54990ba5a20155cab37b82bcd29cf6ba871790e Mon Sep 17 00:00:00 2001 From: Jens H Nielsen Date: Thu, 14 Dec 2017 10:28:53 +0100 Subject: [PATCH 065/104] channel cast to array parameter --- qcodes/instrument/channel.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index a714d244c84..24588994699 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -1,5 +1,5 @@ """ Base class for the channel of an instrument """ -from typing import List, Tuple, Union, Optional, Dict, Sequence +from typing import List, Tuple, Union, Optional, Dict, Sequence, cast from .base import InstrumentBase, Instrument from .parameter import MultiParameter, ArrayParameter @@ -376,18 +376,18 @@ def __getattr__(self, name: str): if isinstance(self._channels[0].parameters[name], ArrayParameter): shapes = tuple(chan.parameters[name].shape for chan in self._channels) - - if self._channels[0].parameters[name].setpoints: + f_parameter = cast(ArrayParameter, self._channels[0].parameters[name]) + if f_parameter.setpoints: setpoints = tuple(chan.parameters[name].setpoints for chan in self._channels) - if self._channels[0].parameters[name].setpoint_names: + if f_parameter.setpoint_names: setpoint_names = tuple(chan.parameters[name].setpoint_names for chan in self._channels) - if self._channels[0].parameters[name].setpoint_labels: + if f_parameter.setpoint_labels: setpoint_labels = tuple( chan.parameters[name].setpoint_labels for chan in self._channels) - if self._channels[0].parameters[name].setpoint_units: + if f_parameter.setpoint_units: setpoint_units = tuple(chan.parameters[name].setpoint_units for chan in self._channels) else: From 7f265211a0a65fc4bdaa19c21b6b096ba413c3dd Mon Sep 17 00:00:00 2001 From: Jens H Nielsen Date: Thu, 14 Dec 2017 11:58:13 +0100 Subject: [PATCH 066/104] mypy channel parameters --- qcodes/instrument/channel.py | 46 +++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index 24588994699..500d889205c 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -2,7 +2,7 @@ from typing import List, Tuple, Union, Optional, Dict, Sequence, cast from .base import InstrumentBase, Instrument -from .parameter import MultiParameter, ArrayParameter +from .parameter import MultiParameter, ArrayParameter, Parameter from ..utils.validators import Validator from ..utils.metadata import Metadatable from ..utils.helpers import full_class @@ -366,30 +366,32 @@ def __getattr__(self, name: str): if isinstance(self._channels[0].parameters[name], MultiParameter): raise NotImplementedError("Slicing is currently not " "supported for MultiParameters") + parameters = cast(List[Union[Parameter, ArrayParameter]], + [chan.parameters[name] for chan in self._channels]) names = tuple("{}_{}".format(chan.name, name) for chan in self._channels) - labels = tuple(chan.parameters[name].label - for chan in self._channels) - units = tuple(chan.parameters[name].unit - for chan in self._channels) - - if isinstance(self._channels[0].parameters[name], ArrayParameter): - shapes = tuple(chan.parameters[name].shape for - chan in self._channels) - f_parameter = cast(ArrayParameter, self._channels[0].parameters[name]) - if f_parameter.setpoints: - setpoints = tuple(chan.parameters[name].setpoints for - chan in self._channels) - if f_parameter.setpoint_names: - setpoint_names = tuple(chan.parameters[name].setpoint_names - for chan in self._channels) - if f_parameter.setpoint_labels: + labels = tuple(parameter.label + for parameter in parameters) + units = tuple(parameter.unit + for parameter in parameters) + + if isinstance(parameters[0], ArrayParameter): + arrayparameters = cast(List[ArrayParameter],parameters) + shapes = tuple(parameter.shape for + parameter in arrayparameters) + if arrayparameters[0].setpoints: + setpoints = tuple(parameter.setpoints for + parameter in arrayparameters) + if arrayparameters[0].setpoint_names: + setpoint_names = tuple(parameter.setpoint_names for + parameter in arrayparameters) + if arrayparameters[0].setpoint_labels: setpoint_labels = tuple( - chan.parameters[name].setpoint_labels - for chan in self._channels) - if f_parameter.setpoint_units: - setpoint_units = tuple(chan.parameters[name].setpoint_units - for chan in self._channels) + parameter.setpoint_labels + for parameter in arrayparameters) + if arrayparameters[0].setpoint_units: + setpoint_units = tuple(parameter.setpoint_units + for parameter in arrayparameters) else: shapes = tuple(() for _ in self._channels) From 88ad86c05b19fe565f3438ec85d0872b445a8c50 Mon Sep 17 00:00:00 2001 From: Jens H Nielsen Date: Thu, 14 Dec 2017 12:13:34 +0100 Subject: [PATCH 067/104] restrict submodules to types that implement the correct submodule --- qcodes/instrument/base.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index d74ff0f02bd..971aa5a0db4 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -3,12 +3,13 @@ import time import warnings import weakref -from typing import Sequence, Optional, Dict, Union, Callable, Any, List +from typing import Sequence, Optional, Dict, Union, Callable, Any, List, TYPE_CHECKING from typing import Dict, Sequence import numpy as np - +if TYPE_CHECKING: + from qcodes.instrumet.channel import ChannelList from qcodes.utils.helpers import DelegateAttributes, strip_attrs, full_class from qcodes.utils.metadata import Metadatable from qcodes.utils.validators import Anything @@ -49,7 +50,7 @@ def __init__(self, name: str, self.parameters = {} # type: Dict[str, _BaseParameter] self.functions = {} # type: Dict[str, Function] - self.submodules = {} # type: Dict[str, Metadatable] + self.submodules = {} # type: Dict[str, Union['InstrumentBase', 'ChannelList']] super().__init__(**kwargs) def add_parameter(self, name: str, @@ -111,7 +112,7 @@ def add_function(self, name: str, **kwargs) -> None: func = Function(name=name, instrument=self, **kwargs) self.functions[name] = func - def add_submodule(self, name: str, submodule: Metadatable) -> None: + def add_submodule(self, name: str, submodule: Union['InstrumentBase', 'ChannelList']) -> None: """ Bind one submodule to this instrument. From 1f38de51bc5b3f57e8093fb6902fe61a7550554b Mon Sep 17 00:00:00 2001 From: Jens H Nielsen Date: Thu, 14 Dec 2017 12:39:03 +0100 Subject: [PATCH 068/104] define class variables at construction time --- qcodes/instrument/base.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index 971aa5a0db4..70ec27684a7 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -356,6 +356,8 @@ class Instrument(InstrumentBase): shared_kwargs = () _all_instruments = {} # type: Dict[str, weakref.ref] + _type = None + _instances = [] # type: List[weakref.ref] def __init__(self, name: str, metadata: Optional[Dict]=None, **kwargs) -> None: From 927f9d39d467a665f4b9a78bcb12f1bdd8d1cbd8 Mon Sep 17 00:00:00 2001 From: Jens H Nielsen Date: Thu, 14 Dec 2017 12:41:42 +0100 Subject: [PATCH 069/104] ignore see https://github.com/python/mypy/issues/1237 --- qcodes/instrument/ip_to_visa.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument/ip_to_visa.py b/qcodes/instrument/ip_to_visa.py index c1eaf14ab6f..3578e791713 100644 --- a/qcodes/instrument/ip_to_visa.py +++ b/qcodes/instrument/ip_to_visa.py @@ -14,7 +14,7 @@ # Such a driver is just a two-line class definition. -class IPToVisa(VisaInstrument, IPInstrument): +class IPToVisa(VisaInstrument, IPInstrument): # type: ignore """ Class to inject an VisaInstrument like behaviour in an IPInstrument that we'd like to use as a VISAInstrument with the @@ -78,5 +78,5 @@ def close(self): self.remove_instance(self) -class AMI430_VISA(AMI430, IPToVisa): +class AMI430_VISA(AMI430, IPToVisa): # type: ignore pass From 6b88c0a1a047a12d0f2b0b5798e24a2c3d885b1b Mon Sep 17 00:00:00 2001 From: Jens H Nielsen Date: Thu, 14 Dec 2017 12:50:34 +0100 Subject: [PATCH 070/104] Annotate ask_raw as the subclass implementation should do --- qcodes/instrument/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index 70ec27684a7..9290b5a4f82 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -652,7 +652,7 @@ def ask(self, cmd: str) -> str: e.args = e.args + ('asking ' + repr(cmd) + ' to ' + inst,) raise e - def ask_raw(self, cmd: str) -> None: + def ask_raw(self, cmd: str) -> str: """ Low level method to write to the hardware and return a response. From 4528e9d5575be8d8b03f0c5e992eaee873172208 Mon Sep 17 00:00:00 2001 From: Jens H Nielsen Date: Thu, 14 Dec 2017 13:02:24 +0100 Subject: [PATCH 071/104] ignore nameerror of get_ipython the nameerror is caught by try/expect --- qcodes/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/__init__.py b/qcodes/__init__.py index d6ebdaa6879..057a185395f 100644 --- a/qcodes/__init__.py +++ b/qcodes/__init__.py @@ -69,7 +69,7 @@ from qcodes.instrument_drivers.test import test_instruments, test_instrument try: - get_ipython() # Check if we are in iPython + get_ipython() # type: ignore # Check if we are in iPython from qcodes.utils.magic import register_magic_class _register_magic = config.core.get('register_magic', False) if _register_magic is not False: From 70c9473d72821dd4a74bcfd87f0102391d204c5f Mon Sep 17 00:00:00 2001 From: Jens H Nielsen Date: Thu, 14 Dec 2017 13:02:46 +0100 Subject: [PATCH 072/104] annotate type of flat_wfmxs --- qcodes/instrument_drivers/tektronix/AWG70000A.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG70000A.py b/qcodes/instrument_drivers/tektronix/AWG70000A.py index 55f6ffaaa6a..07752c12929 100644 --- a/qcodes/instrument_drivers/tektronix/AWG70000A.py +++ b/qcodes/instrument_drivers/tektronix/AWG70000A.py @@ -756,7 +756,7 @@ def makeSEQXFile(trig_waits: Sequence[int], for ch in range(1, chans+1)] # generate wfmx files for the waveforms - flat_wfmxs = [] + flat_wfmxs = [] # type: List[bytes] for amplitude, wfm_lst in zip(amplitudes, wfms): flat_wfmxs += [AWG70000A.makeWFMXFile(wfm, amplitude) for wfm in wfm_lst] From c2b8ea4982f36d46b7a33a8dc9adcd52e8afebf4 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Mon, 18 Dec 2017 10:24:54 +0100 Subject: [PATCH 073/104] add missing import --- qcodes/instrument_drivers/ZI/ZIUHFLI.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qcodes/instrument_drivers/ZI/ZIUHFLI.py b/qcodes/instrument_drivers/ZI/ZIUHFLI.py index 2e274f5916a..6cd8e98bff2 100644 --- a/qcodes/instrument_drivers/ZI/ZIUHFLI.py +++ b/qcodes/instrument_drivers/ZI/ZIUHFLI.py @@ -2,6 +2,7 @@ import logging import numpy as np from functools import partial +from math import sqrt from typing import Callable, List, Union, cast From 4ef3678b27e9081cf9a4d4eb44f26bb03aa2c794 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 12:57:25 +0100 Subject: [PATCH 074/104] dont redefine type --- qcodes/station.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/station.py b/qcodes/station.py index e0a06c77e09..ba8138b7807 100644 --- a/qcodes/station.py +++ b/qcodes/station.py @@ -122,9 +122,9 @@ def add_component(self, component: Metadatable, name: str=None, if name is None: name = getattr(component, 'name', 'component{}'.format(len(self.components))) - name = make_unique(str(name), self.components) - self.components[name] = component - return name + namestr = make_unique(str(name), self.components) + self.components[namestr] = component + return namestr def set_measurement(self, *actions): """ From 3edb39eedbfb8bbc748d610ac31abda77be6802f Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 13:00:59 +0100 Subject: [PATCH 075/104] getting idn may fail --- qcodes/instrument/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index 9290b5a4f82..4f8e4f34ad5 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -396,6 +396,7 @@ def get_idn(self) -> Dict: idstr = self.ask('*IDN?') # form is supposed to be comma-separated, but we've seen # other separators occasionally + idparts = [] for separator in ',;:': # split into no more than 4 parts, so we don't lose info idparts = [p.strip() for p in idstr.split(separator, 3)] From ec629132898b30864312dbe20c21d9219bf4a783 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 13:08:00 +0100 Subject: [PATCH 076/104] Annotate get_idn --- qcodes/instrument/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index 4f8e4f34ad5..670713ecd48 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -374,7 +374,7 @@ def __init__(self, name: str, self.record_instance(self) - def get_idn(self) -> Dict: + def get_idn(self) -> Dict[str, Optional[str]]: """ Parse a standard VISA '\*IDN?' response into an ID dict. @@ -396,7 +396,7 @@ def get_idn(self) -> Dict: idstr = self.ask('*IDN?') # form is supposed to be comma-separated, but we've seen # other separators occasionally - idparts = [] + idparts = [] # type: List[Optional[str]] for separator in ',;:': # split into no more than 4 parts, so we don't lose info idparts = [p.strip() for p in idstr.split(separator, 3)] From 96532ac87be382a0b6d8bba8045091fd9a31615d Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 13:08:22 +0100 Subject: [PATCH 077/104] model may be an empty string --- qcodes/instrument_drivers/rohde_schwarz/ZNB.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/rohde_schwarz/ZNB.py b/qcodes/instrument_drivers/rohde_schwarz/ZNB.py index 9131f242095..f98f998abbe 100644 --- a/qcodes/instrument_drivers/rohde_schwarz/ZNB.py +++ b/qcodes/instrument_drivers/rohde_schwarz/ZNB.py @@ -385,7 +385,11 @@ def __init__(self, name: str, address: str, init_s_params: bool=True, **kwargs) # See page 1025 in the manual. 7.3.15.10 for details of max/min freq # no attempt to support ZNB40, not clear without one how the format # is due to variants - model = self.get_idn()['model'].split('-')[0] + fullmodel = self.get_idn()['model'] + if fullmodel is not None: + model = fullmodel.split('-')[0] + else: + raise RuntimeError("Could not determine ZNB model") # format seems to be ZNB8-4Port if model == 'ZNB4': self._max_freq = 4.5e9 @@ -396,6 +400,8 @@ def __init__(self, name: str, address: str, init_s_params: bool=True, **kwargs) elif model == 'ZNB20': self._max_freq = 20e9 self._min_freq = 100e3 + else: + raise RuntimeError("Unsupported ZNB model {}".format(model)) self.add_parameter(name='num_ports', get_cmd='INST:PORT:COUN?', get_parser=int) From 32600f28236516b64496377c7d65b0a566e4584c Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 13:11:14 +0100 Subject: [PATCH 078/104] annotate _mulval --- qcodes/utils/validators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/utils/validators.py b/qcodes/utils/validators.py index f8d7eeb9bf2..2cccc46032a 100644 --- a/qcodes/utils/validators.py +++ b/qcodes/utils/validators.py @@ -1,5 +1,5 @@ import math -from typing import Union, Tuple, cast +from typing import Union, Tuple, cast, Optional import numpy as np @@ -385,7 +385,7 @@ def __init__(self, divisor: Union[float, int, np.floating], self.precision = precision self._numval = Numbers() if isinstance(divisor, int): - self._mulval = Multiples(divisor=abs(divisor)) + self._mulval = Multiples(divisor=abs(divisor)) # type: Optional[Multiples] else: self._mulval = None self._valid_values = [divisor] From 5957513ad4306424c9a6426c0cf914294b16a997 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 13:52:14 +0100 Subject: [PATCH 079/104] Forward instrument to baseclass instread of setting it manually --- .../instrument_drivers/tektronix/Keithley_2600_channels.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py b/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py index 61401e75d48..f7f0eadc4ac 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py @@ -24,9 +24,8 @@ def __init__(self, name: str, instrument: Instrument) -> None: super().__init__(name=name, shape=(1,), - docstring='Holds a sweep') - - self._instrument = instrument + docstring='Holds a sweep', + instrument=instrument) def prepareSweep(self, start: float, stop: float, steps: int, mode: str) -> None: From 82c2a5242e96b512af8f9c63e2c416ce7e3a2d04 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 14:42:09 +0100 Subject: [PATCH 080/104] better type of instrument --- qcodes/instrument/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index 670713ecd48..d71d2769fa3 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -355,7 +355,7 @@ class Instrument(InstrumentBase): shared_kwargs = () - _all_instruments = {} # type: Dict[str, weakref.ref] + _all_instruments = {} # type: Dict[str, weakref.ref[Instrument]] _type = None _instances = [] # type: List[weakref.ref] From b351713ffd4ee42effa2c00d58d4aed07d7d3faf Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 14:50:58 +0100 Subject: [PATCH 081/104] dont reuse variable name --- qcodes/instrument/parameter.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index fb06716bf92..b8e3090f0e5 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -751,16 +751,16 @@ def __init__(self, name: str, 'when max_val_age is set') self.get_raw = lambda: self._latest['raw_value'] else: - exec_str = instrument.ask if instrument else None - self.get_raw = Command(arg_count=0, cmd=get_cmd, exec_str=exec_str) + exec_str_ask = instrument.ask if instrument else None + self.get_raw = Command(arg_count=0, cmd=get_cmd, exec_str=exec_str_ask) self.get = self._wrap_get(self.get_raw) if not hasattr(self, 'set') and set_cmd is not False: if set_cmd is None: self.set_raw = partial(self._save_val, validate=False)# type: Callable else: - exec_str = instrument.write if instrument else None - self.set_raw = Command(arg_count=1, cmd=set_cmd, exec_str=exec_str)# type: Callable + exec_str_write = instrument.write if instrument else None + self.set_raw = Command(arg_count=1, cmd=set_cmd, exec_str=exec_str_write)# type: Callable self.set = self._wrap_set(self.set_raw) self._meta_attrs.extend(['label', 'unit', 'vals']) From e773ec08098333c83c1a7e96394862e3f21fc91f Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 14:54:32 +0100 Subject: [PATCH 082/104] check that instrument is not none --- .../tektronix/Keithley_2600_channels.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py b/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py index f7f0eadc4ac..9409e600907 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py @@ -68,10 +68,13 @@ def prepareSweep(self, start: float, stop: float, steps: int, def get_raw(self) -> np.ndarray: - data = self._instrument._fast_sweep(self.start, - self.stop, - self.steps, - self.mode) + if self._instrument is not None: + data = self._instrument._fast_sweep(self.start, + self.stop, + self.steps, + self.mode) + else: + raise RuntimeError("No instrument attached to Parameter") return data From 771154e9dfb3c19558b90ac128d75bb264036548 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 15:14:51 +0100 Subject: [PATCH 083/104] add type to _step --- qcodes/instrument/parameter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index b8e3090f0e5..16fc442f845 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -499,7 +499,7 @@ def step(self, step: Union[int, float]): TypeError: if step is not a number """ if step is None: - self._step = step + self._step = step # type: Optional[Union[float, int]] elif not getattr(self.vals, 'is_numeric', True): raise TypeError('you can only step numeric parameters') elif not isinstance(step, (int, float)): From b10e93842d1e1d2425169cfe8874b189c906e4fd Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 15:18:44 +0100 Subject: [PATCH 084/104] cast instrument to inst --- qcodes/instrument/base.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index d71d2769fa3..7a630f6eaf6 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -3,7 +3,7 @@ import time import warnings import weakref -from typing import Sequence, Optional, Dict, Union, Callable, Any, List, TYPE_CHECKING +from typing import Sequence, Optional, Dict, Union, Callable, Any, List, TYPE_CHECKING, cast from typing import Dict, Sequence @@ -575,14 +575,14 @@ def find_instrument(cls, name: str, if ins is None: del cls._all_instruments[name] raise KeyError('Instrument {} has been removed'.format(name)) - + inst = cast('Instrument', ins) if instrument_class is not None: - if not isinstance(ins, instrument_class): + if not isinstance(inst, instrument_class): raise TypeError( 'Instrument {} is {} but {} was requested'.format( - name, type(ins), instrument_class)) + name, type(inst), instrument_class)) - return ins + return inst # `write_raw` and `ask_raw` are the interface to hardware # # `write` and `ask` are standard wrappers to help with error reporting # From ca20b8b4a41cc9ca456850f6c6976d4561ec306b Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 22 Dec 2017 15:28:25 +0100 Subject: [PATCH 085/104] Check type of self_range which could be none --- qcodes/instrument_drivers/yokogawa/GS200.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/yokogawa/GS200.py b/qcodes/instrument_drivers/yokogawa/GS200.py index f3896ebe2cc..7667880f0d2 100644 --- a/qcodes/instrument_drivers/yokogawa/GS200.py +++ b/qcodes/instrument_drivers/yokogawa/GS200.py @@ -1,5 +1,5 @@ from functools import partial -from typing import Optional +from typing import Optional, Union from qcodes import VisaInstrument, InstrumentChannel from qcodes.utils.validators import Numbers, Bool, Enum, Ints @@ -195,7 +195,7 @@ def __init__(self, name: str, address: str, terminator: str="\n", # We want to cache the range value so communication with the instrument only happens when the set the # range. Getting the range always returns the cached value. This value is adjusted when calling # self._set_range - self._cached_range_value = None # type: Optional[float] + self._cached_range_value = None # type: Optional[Union[float,int]] self.add_parameter('voltage_range', label='Voltage Source Range', @@ -382,6 +382,9 @@ def _set_output(self, output_level: float) -> None: if not auto_enabled: self_range = self._cached_range_value + if self_range is None: + raise RuntimeError("Trying to set output but not in" + " auto mode and range is unknown.") else: mode = self._cached_mode if mode == "CURR": @@ -396,6 +399,9 @@ def _set_output(self, output_level: float) -> None: # Update range self.range() self_range = self._cached_range_value + if self_range is None: + raise RuntimeError("Trying to set output but not in" + " auto mode and range is unknown.") # If we are still out of range, raise a value error if abs(output_level) > abs(self_range): raise ValueError("Desired output level not in range [-{self_range:.3}, {self_range:.3}]".format( From 7c2823740c2fc142bdd3d0aeeaab51cc9a2b430e Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Tue, 6 Mar 2018 16:21:28 +0100 Subject: [PATCH 086/104] init returns None --- qcodes/utils/zmq_helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/utils/zmq_helpers.py b/qcodes/utils/zmq_helpers.py index 518f1362836..c0940199d3a 100644 --- a/qcodes/utils/zmq_helpers.py +++ b/qcodes/utils/zmq_helpers.py @@ -16,7 +16,7 @@ class UnboundedPublisher: def __init__(self, topic: str, interface_or_socket: str="tcp://localhost:5559", - context: zmq.Context = None): + context: zmq.Context = None) -> None: """ Args: @@ -49,7 +49,7 @@ class Publisher(UnboundedPublisher): def __init__(self, topic: str, interface_or_socket: str="tcp://localhost:5559", timeout: int = _LINGER*10, - hwm: int = _ZMQ_HWM*5, context: zmq.Context = None): + hwm: int = _ZMQ_HWM*5, context: zmq.Context = None) -> None: """ Args: From e875dfbcf0afb0b5c573397c0bb387a7dd4b8552 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Tue, 6 Mar 2018 16:31:23 +0100 Subject: [PATCH 087/104] Correct typeing for sqlite settings --- qcodes/dataset/sqlite_settings.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_settings.py b/qcodes/dataset/sqlite_settings.py index bd05b9ad1e0..65b821b3b62 100644 --- a/qcodes/dataset/sqlite_settings.py +++ b/qcodes/dataset/sqlite_settings.py @@ -2,7 +2,7 @@ from typing import Tuple, Dict, Union -def _read_settings() -> Tuple[Dict[str, str], +def _read_settings() -> Tuple[Dict[str, Union[str,int]], Dict[str, Union[bool, int, str]]]: """ Function to read the local SQLite settings at import time. @@ -19,6 +19,7 @@ def _read_settings() -> Tuple[Dict[str, str], """ # For the limits, there are known default values # (known from https://www.sqlite.org/limits.html) + DEFAULT_LIMITS: Dict[str, Union[str, int]] DEFAULT_LIMITS = {'MAX_ATTACHED': 10, 'MAX_COLUMN': 2000, 'MAX_COMPOUND_SELECT': 500, @@ -35,6 +36,7 @@ def _read_settings() -> Tuple[Dict[str, str], opt_num = 0 resp = '' + limits: Dict[str, Union[str,int]] limits = DEFAULT_LIMITS.copy() settings = {} @@ -47,6 +49,7 @@ def _read_settings() -> Tuple[Dict[str, str], opt_num += 1 lst = resp.split('=') if len(lst) == 2: + val: Union[str,int] (param, val) = lst if val.isnumeric(): val = int(val) From 604fd93a50a310fc7a7e8e603a940df3451d0f13 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Tue, 6 Mar 2018 16:34:38 +0100 Subject: [PATCH 088/104] add missing type annotation to inits --- qcodes/instrument_drivers/american_magnetics/AMI430.py | 2 +- qcodes/instrument_drivers/rohde_schwarz/ZNB.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/american_magnetics/AMI430.py b/qcodes/instrument_drivers/american_magnetics/AMI430.py index fd1a8c284c3..e643ab40c92 100644 --- a/qcodes/instrument_drivers/american_magnetics/AMI430.py +++ b/qcodes/instrument_drivers/american_magnetics/AMI430.py @@ -28,7 +28,7 @@ def check_enabled_decorator(self, *args, **kwargs): return f(self, *args, **kwargs) return check_enabled_decorator - def __init__(self, parent: 'AMI430'): + def __init__(self, parent: 'AMI430') -> None: super().__init__(parent, "SwitchHeater") # Add state parameters diff --git a/qcodes/instrument_drivers/rohde_schwarz/ZNB.py b/qcodes/instrument_drivers/rohde_schwarz/ZNB.py index 084fe1716b6..b3a7af0934b 100644 --- a/qcodes/instrument_drivers/rohde_schwarz/ZNB.py +++ b/qcodes/instrument_drivers/rohde_schwarz/ZNB.py @@ -94,7 +94,7 @@ def get_raw(self): class ZNBChannel(InstrumentChannel): - def __init__(self, parent, name, channel, vna_parameter: str=None): + def __init__(self, parent, name, channel, vna_parameter: str=None) -> None: """ Args: parent: Instrument that this channel is bound to. From 17dca98bbe8ba8d9ceeb1e04ed7ffec880d695ae Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Tue, 6 Mar 2018 16:55:51 +0100 Subject: [PATCH 089/104] fix what appears to be a real bug found by mypy --- qcodes/dataset/measurements.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index e44b2a7b19a..04857d0140c 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -37,7 +37,7 @@ def __init__(self, dataset: DataSet, write_period: float, self._known_parameters = list(parameters.keys()) self._results: List[dict] = [] # will be filled by addResult self._last_save_time = monotonic() - self._known_dependencies: Dict[str, str] = {} + self._known_dependencies: Dict[str, List[str]] = {} for param, parspec in parameters.items(): if parspec.depends_on != '': self._known_dependencies.update({str(param): @@ -144,6 +144,7 @@ def add_result(self, # For compatibility with the old Loop, setpoints are # tuples of numbers (usually tuple(np.linspace(...)) if hasattr(value, '__len__') and not(isinstance(value, str)): + value = cast(Union[Sequence,np.ndarray], value) res_dict.update({param: value[index]}) else: res_dict.update({param: value}) @@ -219,7 +220,7 @@ def __enter__(self) -> DataSaver: # next set up the "datasaver" if self.experiment: - eid = self.experiment.id + eid = self.experiment.exp_id else: eid = None @@ -390,6 +391,7 @@ def register_parameter( name = str(parameter) if isinstance(parameter, ArrayParameter): + parameter = cast(ArrayParameter, parameter) if parameter.setpoint_names: spname = (f'{parameter._instrument.name}_' f'{parameter.setpoint_names[0]}') From bb7e249c61e0d5bbe7204992c4ce7c2ce6dd95c1 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Mar 2018 15:46:19 +0100 Subject: [PATCH 090/104] dont reuse variable name --- qcodes/dataset/experiment_container.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/experiment_container.py b/qcodes/dataset/experiment_container.py index db0a0cc9a21..36ecd435ec0 100644 --- a/qcodes/dataset/experiment_container.py +++ b/qcodes/dataset/experiment_container.py @@ -236,8 +236,8 @@ def load_experiment_by_name(name: str, for row in rows: s = f"exp_id:{row['exp_id']} ({row['name']}-{row['sample_name']}) started at({row['start_time']})" _repr.append(s) - _repr = "\n".join(_repr) - raise ValueError(f"Many experiments matching your request found {_repr}") + _repr_str = "\n".join(_repr) + raise ValueError(f"Many experiments matching your request found {_repr_str}") else: e.exp_id = rows[0]['exp_id'] return e From 3db5264de1b0645af37c4b4e0cabd0b79865f89f Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Mar 2018 15:49:01 +0100 Subject: [PATCH 091/104] block mypy 0.570 due to xml issue --- test_requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_requirements.txt b/test_requirements.txt index 83ffed6c3e2..b364fdd5bbb 100644 --- a/test_requirements.txt +++ b/test_requirements.txt @@ -3,7 +3,7 @@ pytest-cov pytest codacy-coverage hypothesis -mypy +mypy!=0.570 # due to https://github.com/python/mypy/issues/4674 git+https://github.com/QCoDeS/pyvisa-sim.git lxml codecov From 616a7c8a6d4228ab65f3b1414b63436a39dc71e7 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Mar 2018 16:21:33 +0100 Subject: [PATCH 092/104] dont reuse setpoints variable --- qcodes/dataset/measurements.py | 10 ++++++---- qcodes/utils/validators.py | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index 04857d0140c..6c3b9ee4c46 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -410,8 +410,10 @@ def register_parameter( label=splabel, unit=spunit) self.parameters[spname] = sp - setpoints = setpoints if setpoints else () - setpoints += (spname,) + my_setpoints: Tuple[Union[_BaseParameter, str], ...] = setpoints if setpoints else () + my_setpoints += (spname,) + else: + my_setpoints = setpoints # We currently treat ALL parameters as 'numeric' and fail to add them # to the dataset if they can not be unraveled to fit that description @@ -424,8 +426,8 @@ def register_parameter( label = parameter.label unit = parameter.unit - if setpoints: - sp_strings = [str(sp) for sp in setpoints] + if my_setpoints: + sp_strings = [str(sp) for sp in my_setpoints] else: sp_strings = [] if basis: diff --git a/qcodes/utils/validators.py b/qcodes/utils/validators.py index 2cccc46032a..f559550713e 100644 --- a/qcodes/utils/validators.py +++ b/qcodes/utils/validators.py @@ -407,7 +407,7 @@ def validate(self, value: Union[float, int, np.floating], # multiply our way out of the problem by constructing true # multiples in the relevant range and see if `value` is one # of them (within rounding errors) - divs = int(divmod(value, self.divisor)[0]) + divs = int(divmod(value, self.divisor)[0]) # type: ignore true_vals = np.array([n*self.divisor for n in range(divs, divs+2)]) abs_errs = [abs(tv-value) for tv in true_vals] if min(abs_errs) > self.precision: From 56547c8a6ba2d1a78244786e49f8f3129fa68e42 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Mar 2018 16:30:52 +0100 Subject: [PATCH 093/104] Cast parameter before getting unit and label --- qcodes/dataset/measurements.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index 6c3b9ee4c46..28844b259f8 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -11,7 +11,7 @@ import qcodes as qc from qcodes import Station -from qcodes.instrument.parameter import ArrayParameter, _BaseParameter +from qcodes.instrument.parameter import ArrayParameter, _BaseParameter, Parameter from qcodes.dataset.experiment_container import Experiment from qcodes.dataset.param_spec import ParamSpec from qcodes.dataset.data_set import DataSet @@ -422,6 +422,7 @@ def register_parameter( # requirement later and start saving binary blobs with the datasaver, # but for now binary blob saving is referred to using the DataSet # API directly + parameter = cast(Union[Parameter, ArrayParameter], parameter) paramtype = 'numeric' label = parameter.label unit = parameter.unit From b362fd77d0e2b00ae4e4d60710a781412e4d914b Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Mar 2018 16:48:50 +0100 Subject: [PATCH 094/104] Sqlite rows can be indexed both by index and column name --- qcodes/dataset/sqlite_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index fd218c9ae96..fd74d96e747 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -107,7 +107,7 @@ def _convert_array(text: bytes) -> ndarray: return np.load(out) -def one(curr: sqlite3.Cursor, column: str) -> Any: +def one(curr: sqlite3.Cursor, column: Union[int, str]) -> Any: """Get the value of one column from one row Args: curr: cursor to operate on From aba9deb145408c5ab6d2e7ea353f3d1d3569418f Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Mar 2018 16:56:41 +0100 Subject: [PATCH 095/104] mypy does not like the reuse of _ --- qcodes/dataset/data_set.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 87d7841e1b0..17e7d22c750 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -179,8 +179,8 @@ def _new(self, name, exp_id, specs: SPECS = None, values=None, Actually perform all the side effects needed for the creation of a new dataset. """ - _, run_id, _ = create_run(self.conn, exp_id, name, - specs, values, metadata) + _, run_id, __ = create_run(self.conn, exp_id, name, + specs, values, metadata) # this is really the UUID (an ever increasing count in the db) self.run_id = run_id From 717c928f805c2f8e3414938e7b144fcb32b92e6b Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Mar 2018 16:57:09 +0100 Subject: [PATCH 096/104] this is a list of values not a list of lists of values --- qcodes/dataset/data_set.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 17e7d22c750..5d6e0a912f4 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -440,7 +440,7 @@ def modify_results(self, start_index: int, flattened_keys, flattened_values) - def add_parameter_values(self, spec: ParamSpec, values: List[VALUES]): + def add_parameter_values(self, spec: ParamSpec, values: VALUES): """ Add a parameter to the DataSet and associates result values with the new parameter. From 80a436fddb135471344b014017ba448d9ca6e00c Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 4 Apr 2018 13:15:48 +0200 Subject: [PATCH 097/104] make sure that params_ is a list before appending --- qcodes/instrument_drivers/stanford_research/SR86x.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qcodes/instrument_drivers/stanford_research/SR86x.py b/qcodes/instrument_drivers/stanford_research/SR86x.py index 016c0b5a179..e3dab3547e7 100644 --- a/qcodes/instrument_drivers/stanford_research/SR86x.py +++ b/qcodes/instrument_drivers/stanford_research/SR86x.py @@ -150,6 +150,7 @@ def snapshot_base(self, update: bool = False, # it can only be read after a completed capture and will # timeout otherwise when the snapshot is updated, e.g. at # station creation time + params_to_skip_update = list(params_to_skip_update) params_to_skip_update.append('count_capture_kilobytes') snapshot = super().snapshot_base(update, params_to_skip_update) From 3b2f972b8835629729c7a0b1cb6298b674faa9d3 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 4 Apr 2018 13:16:19 +0200 Subject: [PATCH 098/104] there seems to be a mypy issues with alias like this --- qcodes/dataset/plotting.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/qcodes/dataset/plotting.py b/qcodes/dataset/plotting.py index d3be9e6759b..720c0cbd8d5 100644 --- a/qcodes/dataset/plotting.py +++ b/qcodes/dataset/plotting.py @@ -13,11 +13,10 @@ log = logging.getLogger(__name__) DB = qc.config["core"]["db_location"] -mplaxes = matplotlib.axes.Axes def plot_by_id(run_id: int, - axes: Optional[Union[mplaxes, - Sequence[mplaxes]]]=None) -> List[mplaxes]: + axes: Optional[Union[matplotlib.axes.Axes, + Sequence[matplotlib.axes.Axes]]]=None) -> List[matplotlib.axes.Axes]: def set_axis_labels(ax, data): if data[0]['label'] == '': lbl = data[0]['name'] @@ -50,7 +49,7 @@ def set_axis_labels(ax, data): """ alldata = get_data_by_id(run_id) nplots = len(alldata) - if isinstance(axes, mplaxes): + if isinstance(axes, matplotlib.axes.Axes): axes = [axes] if axes is None: @@ -115,7 +114,7 @@ def set_axis_labels(ax, data): def plot_on_a_plain_grid(x: np.ndarray, y: np.ndarray, z: np.ndarray, - ax: mplaxes) -> mplaxes: + ax: matplotlib.axes.Axes) -> matplotlib.axes.Axes: """ Plot a heatmap of z using x and y as axes. Assumes that the data are rectangular, i.e. that x and y together describe a rectangular From 7c771e2cc65fe3788b31b88bdbefaf9885896f53 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 4 Apr 2018 13:16:37 +0200 Subject: [PATCH 099/104] help mypy a bit --- qcodes/dataset/measurements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index 843b35d8664..7924fc79934 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -29,7 +29,7 @@ class DataSaver: datasaving to the database """ - default_callback = None + default_callback: Optional[dict] = None def __init__(self, dataset: DataSet, write_period: float, parameters: Dict[str, ParamSpec]) -> None: From 1cd0264224d6e671c4957869f2281b62188b45fc Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 4 Apr 2018 13:19:42 +0200 Subject: [PATCH 100/104] monitor wrong exception --- qcodes/monitor/monitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 135b548b35d..b0585a780fa 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -168,7 +168,7 @@ def join(self, timeout=None) -> None: except RuntimeError as e: # the above may throw a runtime error if the loop is already # stopped in which case there is nothing more to do - log.exception(e) + log.exception("Could not close loop") while not self.loop_is_closed: log.debug("waiting for loop to stop and close") time.sleep(0.01) From 8528c7f5d16ce4e4938591a35eff4e05c4e9412a Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 4 Apr 2018 13:25:00 +0200 Subject: [PATCH 101/104] wrong variable --- qcodes/instrument_drivers/tektronix/AWG70000A.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG70000A.py b/qcodes/instrument_drivers/tektronix/AWG70000A.py index 1b09a1e5783..a69667ca0b0 100644 --- a/qcodes/instrument_drivers/tektronix/AWG70000A.py +++ b/qcodes/instrument_drivers/tektronix/AWG70000A.py @@ -262,7 +262,7 @@ def setWaveform(self, name: str) -> None: if name not in self.root_instrument.waveformList: raise ValueError('No such waveform in the waveform list') - self.root_instrument.write(f'SOURce{channel}:CASSet:WAVeform "{name}"') + self.root_instrument.write(f'SOURce{self.channel}:CASSet:WAVeform "{name}"') def setSequenceTrack(self, seqname: str, tracknr: int) -> None: """ From eb7b356b2e908d7da40de5782ce43aa60ea88cb0 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 4 Apr 2018 13:25:22 +0200 Subject: [PATCH 102/104] cast to int to help mypy --- qcodes/dataset/sqlite_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index d4d1e21bd5e..5ae4c2d038a 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -408,11 +408,11 @@ def insert_many_values(conn: sqlite3.Connection, # According to the SQLite changelog, the version number # to check against below # ought to be 3.7.11, but that fails on Travis - if LooseVersion(version) <= LooseVersion('3.8.2'): + if LooseVersion(str(version)) <= LooseVersion('3.8.2'): max_var = qc.SQLiteSettings.limits['MAX_COMPOUND_SELECT'] else: max_var = qc.SQLiteSettings.limits['MAX_VARIABLE_NUMBER'] - rows_per_transaction = int(max_var/no_of_columns) + rows_per_transaction = int(int(max_var)/no_of_columns) _columns = ",".join(columns) _values = "(" + ",".join(["?"] * len(values[0])) + ")" From 4aaec3ace88b06a3d270d6d5df591f0eb5455d50 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 4 Apr 2018 13:34:48 +0200 Subject: [PATCH 103/104] avoid using global --- qcodes/utils/helpers.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qcodes/utils/helpers.py b/qcodes/utils/helpers.py index c2a4fd23174..9ade2ca6847 100644 --- a/qcodes/utils/helpers.py +++ b/qcodes/utils/helpers.py @@ -504,13 +504,12 @@ def add_to_spyder_UMR_excludelist(modulename: str): if any('SPYDER' in name for name in os.environ): try: - from spyder.utils.site.sitecustomize import UserModuleReloader - global __umr__ + from spyder.utils.site import sitecustomize excludednamelist = os.environ.get('SPY_UMR_NAMELIST', '').split(',') if modulename not in excludednamelist: log.info("adding {} to excluded modules".format(modulename)) excludednamelist.append(modulename) - __umr__ = UserModuleReloader(namelist=excludednamelist) + sitecustomize.__umr__ = sitecustomize.UserModuleReloader(namelist=excludednamelist) except ImportError: pass From e4b0fe3b5c876bc8c69f99eb93f5d5ab48f055ed Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 4 Apr 2018 14:07:55 +0200 Subject: [PATCH 104/104] python 3.6 style types --- qcodes/config/config.py | 4 ++-- qcodes/data/data_set.py | 2 +- qcodes/instrument/base.py | 2 -- qcodes/instrument/channel.py | 4 ++-- qcodes/instrument/parameter.py | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/qcodes/config/config.py b/qcodes/config/config.py index 4d8518c25df..85b5056c35c 100644 --- a/qcodes/config/config.py +++ b/qcodes/config/config.py @@ -88,8 +88,8 @@ class Config(): defaults = None defaults_schema = None - _diff_config = {} # type: Dict[str, dict] - _diff_schema = {} # type: Dict[str, dict] + _diff_config: Dict[str, dict] = {} + _diff_schema: Dict[str, dict] = {} def __init__(self): self.defaults, self.defaults_schema = self.load_default() diff --git a/qcodes/data/data_set.py b/qcodes/data/data_set.py index e389218bcae..b1c25f7991f 100644 --- a/qcodes/data/data_set.py +++ b/qcodes/data/data_set.py @@ -169,7 +169,7 @@ class DataSet(DelegateAttributes): default_formatter = GNUPlotFormat() location_provider = FormatLocation() - background_functions = OrderedDict() # type: Dict[str, Callable] + background_functions: Dict[str, Callable] = OrderedDict() def __init__(self, location=None, arrays=None, formatter=None, io=None, write_period=5): diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index 2df01c94b36..2c88743fc37 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -5,8 +5,6 @@ import weakref from typing import Sequence, Optional, Dict, Union, Callable, Any, List, TYPE_CHECKING, cast - -from typing import Dict, Sequence import numpy as np if TYPE_CHECKING: from qcodes.instrumet.channel import ChannelList diff --git a/qcodes/instrument/channel.py b/qcodes/instrument/channel.py index 07b70285991..26acccc9dbb 100644 --- a/qcodes/instrument/channel.py +++ b/qcodes/instrument/channel.py @@ -171,13 +171,13 @@ def __init__(self, parent: Instrument, self._snapshotable = snapshotable self._paramclass = multichan_paramclass - self._channel_mapping = {} # type: Dict[str, InstrumentChannel] + self._channel_mapping: Dict[str, InstrumentChannel] = {} # provide lookup of channels by name # If a list of channels is not provided, define a list to store # channels. This will eventually become a locked tuple. if chan_list is None: self._locked = False - self._channels = [] # type: Union[List[InstrumentChannel],Tuple[InstrumentChannel, ...]] + self._channels: Union[List[InstrumentChannel],Tuple[InstrumentChannel, ...]] = [] else: self._locked = True self._channels = tuple(chan_list) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 3ac7670b157..015c4256031 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -59,7 +59,7 @@ import os import collections import warnings -from typing import Optional, Sequence, TYPE_CHECKING, Union, Callable, List, Dict, Any, Sized, cast +from typing import Optional, Sequence, TYPE_CHECKING, Union, Callable, List, Dict, Any, Sized from functools import partial, wraps import numpy